天天看點

【超詳細解釋】從Java NIO到Netty的每一步 (五)

Netty 元件介紹

因為Netty被用于架構或者中間件底層通訊,是以平時我并沒有直接基于Netty進行程式設計過,是以先大概讀一下使用者手冊,發現使用者手冊Netty對基本概念兩三句話概括了之,是以自己先研究了下Netty核心元件的基本概念,之後再去讀源碼。

從抛棄服務代碼講起

package netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class DiscardServer {
    private int port;

    public DiscardServer(int port) {
        this.port = port;
    }

    public void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
        EventLoopGroup workerGroup = new NioEventLoopGroup();// (1)
        try {
            // Netty的服務啟用類
            ServerBootstrap b = new ServerBootstrap(); 
            b.group(bossGroup, workerGroup) // (1)
                    // 簡單了解為Netty自己寫了一個ServerSocketChannel接收連接配接請求
                    .channel(NioServerSocketChannel.class) 
                    // 可以了解我們給SocketChannel添加handler對其進行處理
                    .childHandler(new ChannelInitializer<SocketChannel>() { 
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new DiscardServerHandler()); //(2)
                        }
                    })
                    //對NioServerSocketChannel進行配置
                    .option(ChannelOption.SO_BACKLOG, 128)  
                    //對SocketChannel進行配置
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            // 綁定端口開始接收請求
            ChannelFuture f = b.bind(port).sync();
            // 簡單了解為關閉服務
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        int port = 8080;
        if (args.length > 0) {
            port = Integer.parseInt(args[0]);
        }

        new DiscardServer(port).run();
    }
}      
package netty;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
 * 自定義處理I/O請求
 */
public class DiscardServerHandler extends ChannelInboundHandlerAdapter {//(3)

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        // 丢棄接收到的資料.
        ((ByteBuf) msg).release(); 
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // 當發生異常時關閉連接配接.
        cause.printStackTrace();
        ctx.close();
    }

}      

關注我日常更新分享Java程式設計技術!希望大家都能早日走上人生巅峰