Hello Netty

經過java進行網絡編程,netty能夠提升網絡通訊的開發效率的同時大大提升網絡通訊的效率。下面來看下如何使用netty進行高效編程。java

引入依賴

<dependency>
    <groupId>io.netty</gro
    <artifactId>netty-all</artifactId>
    <version>4.0.25.Final</version>
</dependency>

netty3和netty4在編程api上有必定的區別,本篇是經過netty4進行實踐的。編程

服務端句柄對象io.netty.bootstrap.ServerBootstrap

netty服務端和客戶端的建立都是依賴於Bootstrap句柄對象,下面咱們看下服務端是如何經過ServerBootstrap建立服務的。bootstrap

serverBootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup()).channel(NioServerSocketChannel.class)
    .localAddress(new InetSocketAddress(nettyServerConfig.getListenPort()))
    .childHandler(new ChannelInitializer<SocketChannel>() {
        @Override
        public void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline().addLast(
                    new NettyEncoder(),
                    new NettyDecoder(),
                    new NettyConnetManageHandler(),
                    new EchoServerHandler());
        }
    });

ChannelFuture f = serverBootstrap.bind().sync();

你們去看源碼就能夠知道上面都是在初始化ServerBootstrap對象的屬性:api

  • io.netty.bootstrap.ServerBootstrap#group(io.netty.channel.EventLoopGroup, io.netty.channel.EventLoopGroup)第一個參數是用於接收請求的EventLoopGroup,第二個參數是處理請求的EventLoopGroup。網絡

  • io.netty.bootstrap.AbstractBootstrap#channel用於初始化channelFactory,channel建立爲NioServerSocketChannel的類型。ide

  • io.netty.bootstrap.AbstractBootstrap#localAddress(java.net.SocketAddress)這個沒什麼好說的設置監聽的地址。oop

  • io.netty.bootstrap.ServerBootstrap#childHandler數據流的handler處理器,上面咱們設置了四個handler,分別有數據流出和流進是待處理的handler鏈。學習

  • 上面都是在初始化句柄接下來,serverBootstrap.bind().sync()同步開啓服務。.net

客戶端句柄對象io.netty.bootstrap.Bootstrap

bootstrap.group(new NioEventLoopGroup()).channel(NioSocketChannel.class)
    .handler(new ChannelInitializer<SocketChannel>() {
        @Override
        public void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline().addLast(
                    new NettyEncoder(),
                    new NettyDecoder(),
                    new NettyClientHandler());
        }
    });

bootstrap.connect(new InetSocketAddress(ip, port));

客戶端句柄初始化相對來講簡單,初始化處理EventLoopGroup,channel factory,handler處理鏈,最後connect就能夠鏈接到netty的服務端了。netty

handler實現

一、NettyEncoder

public class NettyEncoder extends MessageToByteEncoder<NettyCommand> {

    @Override
    public void encode(ChannelHandlerContext ctx, NettyCommand msg, ByteBuf out)
            throws Exception {

        out.writeBytes(msg.encode());
    }
}

二、NettyDecoder

public class NettyDecoder extends ByteToMessageDecoder {

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        byte[] tmpBuf = new byte[in.readableBytes()];
        in.readBytes(tmpBuf);
        NettyCommand command = new NettyCommand();
        out.add(command.decode(tmpBuf));
    }
}

傳輸對象的encode和decode都依賴於自定義的NettyCommand進行定義。

三、EchoServerHandler

class EchoServerHandler extends ChannelInboundHandlerAdapter {

        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            System.out.println("phase: channelReadComplete");
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx,
                                    Throwable cause) {
            System.out.println("phase: exceptionCaught");
            cause.printStackTrace();
            ctx.close();
        }

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            NettyCommand requestCommand = (NettyCommand) msg;
            System.out.println("Server received: " + new String(requestCommand.getBody()));

            processMessageReceive(ctx, requestCommand);
        }

    }

四、NettyClientHandler

class NettyClientHandler extends SimpleChannelInboundHandler<NettyCommand> {

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

        @Override
        protected void channelRead0(ChannelHandlerContext ctx, NettyCommand msg)
                throws Exception {
            NettyCommand command = (NettyCommand) msg;
            processMessageReceive(ctx, command);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx,
                                    Throwable cause) {                    //4
            System.out.println("exceptionCaught");
            cause.printStackTrace();
            ctx.close();
        }

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

到這裏一個簡單的hello netty就實現完畢了。

後記

到這裏整個腦殼還不是太清晰,多是由於初次使用netty,不少深刻的原理性東西尚未充分的認識到,後面不斷學習昇華。

相關文章
相關標籤/搜索