JAVA netty 简单使用

实现一个功能,客户端和服务器 轮流对一个数加+1
服务器

public class Server {
    public static void main(String[] args) {
        NioEventLoopGroup boss=new NioEventLoopGroup(1);
        NioEventLoopGroup worker=new NioEventLoopGroup(3);
        try {
            final ServerBootstrap server=new ServerBootstrap();
            server.group(boss,worker).channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new ServerHandler());
                        }
                    });
            ChannelFuture future = server.bind(8881).sync();
            future.channel().closeFuture().sync();
        }catch (Exception e){
            e.printStackTrace();
        }
        finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }
}

服务器handler

netty ChannelHandler 类似 spring mvc的filter,使用的是责任链模式,可以对客户端传来的数据进行层层解析,解码等操作。
在没有任何特殊操作下,默认传递在责任中的对象是ByteBuf

public class ServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {//msg 其实就是个ByteBuf 对象
        ByteBuf buf=(ByteBuf) msg;
        int i = buf.readInt();
        System.out.println("服务器收到客户端消息"+ctx.channel().remoteAddress()+" "+i);
        ByteBuf newbuf=ctx.alloc().buffer(1024);
        newbuf.writeInt(i+1);
        ctx.writeAndFlush(newbuf);
        buf.release();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channel active");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

客户端

public class Client {
    public static void main(String[] args) {
        NioEventLoopGroup boss=new NioEventLoopGroup(1);
        try {
            final Bootstrap client=new Bootstrap();
            client.group(boss).channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new ClientHandler());
                        }
                    });
            ChannelFuture future = client.connect("127.0.0.1",8881).sync();
            future.channel().closeFuture().sync();
        }catch (Exception e){
            e.printStackTrace();
        }
        finally {
            boss.shutdownGracefully();
        }
    }
}

客户端handlr

public class ClientHandler extends SimpleChannelInboundHandler {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf=(ByteBuf)msg;
        int i=buf.readInt();
        System.out.println("客服端收到服务器"+ctx.channel().remoteAddress()+"---> "+i);
        Thread.sleep(2000);
        ByteBuf newbuf = ctx.alloc().buffer(1024);
        newbuf.writeInt(i+1);
        ctx.writeAndFlush(newbuf);
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        System.out.println("连接服务器成功");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ByteBuf buffer = ctx.alloc().buffer(1024);
        buffer.writeInt(1);
        ctx.writeAndFlush(buffer);
    }
}


一开始很疑惑,channelRead0(ChannelHandlerContext ctx, Object msg) 方法里的msg 到底是个什么对象?
在添加其它handler之后,比如一个StringDecode,netty会自动的把ByteBuf里的字节转String,并传递在Object对象中。这是Object就是一个String。
翻了下源码,还是很清晰的
在ChannelHandlerContext 接口中有一个fireChannelRead 方法,这个方法的解释如下

ChannelHandlerContext fireChannelRead(java.lang.Object msg)
Description copied from interface: ChannelInboundInvoker
A Channel received a message. This will result in having the ChannelInboundHandler.channelRead(ChannelHandlerContext, Object) method called of the next ChannelInboundHandler contained in the ChannelPipeline of the Channel.
Specified by:
fireChannelRead in interface ChannelInboundInvoker

简单来就是会调用handler 责任链的下一个处理类。同过fireChannelRead方法,可以给下一个责任链传递一个对象msg,这个msg会传递到下一个处理类的 ChannelRead方法上。例如,StringDecode把ByteBuf转为一个String对象msg,在调用fireChannelRead(msg),就把这个String传到下一个handler去了。
channelRead0也是同样的意思


netty是基于nio的框架,要是理解了nio,其实操作起来也不是很费劲。

原文地址:https://www.cnblogs.com/duangL/p/11629840.html

时间: 2024-10-05 07:38:30

JAVA netty 简单使用的相关文章

Netty简单应用与线上服务器部署_netty视频

Netty简单应用与线上服务器部署 课程学习地址:http://www.xuetuwuyou.com/course/198 课程出自学途无忧网:http://www.xuetuwuyou.com 一.开发环境 4.1.11.Final   jdk1.8 maven 3.2 Spring 4.3.9 二.适合人群 ①想深入学习java ClassLoader ②想在线上linux服务器上运行netty或Springboot服务 三.课程目标 ①掌控ClassLoader ②学会编写shell脚本

学习 java netty (一) -- java nio

前言:最近在研究java netty这个网络框架,第一篇先介绍java的nio. java nio在jdk1.4引入,其实也算比较早的了,主要引入非阻塞io和io多路复用.内部基于reactor模式. nio核心: - buffer - channel - selector buffer: 类似网络编程中的缓冲区,有 ByteBuffer 字节 CharBuffer 字符 IntBuffer DoubleBuffer- 常用的有ByteBuffer和CharBuffer java nio buf

学习 java netty (三) -- Channel

学习 java netty (三) – Channel 前言:netty封装的channel,看一下官网的定义 A nexus to a network socket or a component which is capable of I/O operations such as read, write, connect, and bind. 可以I/O操作(如读,写,连接和绑定)的连网套接字或组件 A channel provides a user: All I/O operations a

学习 java netty (二) -- ServerBootstrap

前言:我们自己使用java nio开发网络程序是非常繁琐的,netty为我们做好了一切,其中ServerBootstrap是一个启动辅助类,了解它我们就能开发出简单的nio 服务端程序. 不理解Nio中channel和handler等可参考上一篇文章 学习 java netty (一) – java nio ServerBootstrap(): //创建一个ServerBootstrap对象 ServerBootstrap server = new ServerBootstrap; Server

java netty socket库和自定义C#socket库利用protobuf进行通信完整实例

之前的文章讲述了socket通信的一些基本知识,已经本人自定义的C#版本的socket.和java netty 库的二次封装,但是没有真正的发表测试用例. 本文只是为了讲解利用protobuf 进行C# 和 java的通信.以及完整的实例代码 java 代码 svn 地址,本人开发工具是NetBeans 8.0.2 使用 maven 项目编译 http://code.taobao.org/svn/flynetwork_csharp/trunk/BlogTest c# 代码 svn 地址 使用的是

使用java搭建简单的ligerui环境

最近因为工作需要,学习了ligerui框架.但是,因为在公司,我们只是作为最低层的码农,所以环境都已经搭建好了,我们这些码农平时都是直接拿到工程,然后在别人的框架上不断的ctrl + c.ctrl + v,然后修修补补.所以为了摆脱这种困境,决定自己使用简单的servlet搭建一个ligerui,然后测试下ligerui这玩意到底是怎么跑起来的. 1.下载ligerui相关组件.这个很简单,直接去www.ligerui.com即可找到. 2.使用Eclipse创建一个web工程,然后搭建下面这个

Java数据类型简单总结

Java数据类型简单总结 一:Java数据类型总的分为两大类:基本数据类型和引用数据类型. 基本数据类型:byte.short.int.long.float.double.char.boolean八种. 引用数据类型: 1:除了基本数据类型之外都是引用数据类型, 2:API类:String.File 3:自定义类:Test01...... 4:数组:int [ ].String [ ] 二:基本数据类型 1:分类 数据类型 位(bit) 取值范围 数据类型 位 取值范围 byte 8 -128~

Java对象简单实用(计算器案例)

Java对象简单实用(计算器案例) 对 Java中的对象与属性,方法的使用,简单写了个案例 1 import java.util.Scanner; 2 class Calculste 3 { 4 int a; //定义两个整数 5 int b; 6 String option; //定义接收操作符的字符串 7 public void count(){ 8 9 //对操作符进行判断 10 switch(option){ 11 case "+": 12 System.out.println

Java实现简单版SVM

最近的图像分类工作要用到latent svm,为了更加深入了解svm,自己动手实现一个简单版的. 之所以说是简单版,因为没有用到拉格朗日,对偶,核函数等等.而是用最简单的梯度下降法求解.其中的数学原理我参考了http://blog.csdn.net/lifeitengup/article/details/10951655,文中是用matlab实现的svm. 源代码和数据集下载:https://github.com/linger2012/simpleSvm 其中数据集来自于libsvm,我找了其中