码迷,mamicode.com
首页 > 编程语言 > 详细

JAVA netty 简单使用

时间:2019-10-07 13:21:51      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:rem   except   thread   nec   功能   invoke   自动   fir   模式   

实现一个功能,客户端和服务器 轮流对一个数加+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,其实操作起来也不是很费劲。

JAVA netty 简单使用

标签:rem   except   thread   nec   功能   invoke   自动   fir   模式   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!