netty-1

组件

从Echo开始,《netty》实战上的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
EventLoopGroup group=new NioEventLoopGroup();
try{
Bootstrap b=new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress(host,port))
.handler(new ChannelInitializer<SocketChannel>() {

protected void initChannel(SocketChannel ch) throws Exception {

ch.pipeline().addLast(new EchoClientHandler());
}
});
ChannelFuture f=b.connect().sync();
f.channel().closeFuture().sync();
}finally {
group.shutdownGracefully();
}

Bootstrap 是引导类,ServerBootstrap有两个EventLoopGroup,一个为传入连接请求创建Channel,一个

NioEventLoopGroup相当于线程池,包含多个EventLoop, EventLoop只和一个Thread绑定。channel注册到一个EventLoop。

对接收到的数据进行处理是在pipeline中,pipeline包含出站(ChannelOutboundHandler)和入站(ChannelInboundhandler),入站顺序按照pipeline添加handler的顺序,出站相反。因此要对数据进行处理(编码,解码等)都是写ChannelHandler添加到pipeline中。

Netty中有大量的ChannelHandler默认实现,只需要重写特殊处理的方法。

编码和解码有一些基类:ByteToMessageDecoder,MessageToByteEncoder,作用和名字一样。

NioSocketChannel,是异步的客户端TCP 连接,NioServerSocketChannel表示的是服务端。根据不同的协议类型还有NioDatagramChannel,表示UDP连接,NioSctpChannel,Sctp连接。

NioSocketChannel通过工厂方法来新建实例。

1
2
3
4
5
6
7
public B channel(Class<? extends C> channelClass) {
if (channelClass == null) {
throw new NullPointerException("channelClass");
} else {
return this.channelFactory(new AbstractBootstrap.BootstrapChannelFactory(channelClass));
}
}

BootstrapChannelFactory工厂中的 newChannel() 方法:return (Channel)this.clazz.newInstance();

Channel的实例化实在 b.connect()的时候进行的。返回值都是 ChannelFuture, 这几个方法都是在BootStrap或者父类AbstractBootStrap(ServerBootStrap和bootStrap的共有方法)中,

connect() -> doResolveAndConnect() -> initAndRegister()

1
2
3
4
5
6
7
8
final ChannelFuture initAndRegister() {
Channel channel = null;
try {
channel = this.channelFactory.newChannel();
this.init(channel);
} catch (Throwable var3) {
……
}

在 NioSocketChannel构造中,最终生成到Java中socketChannel,在AbstractNioChannel中设置channel.configureBlocking(false)readInterestOp=SelectionKey.OP_READ,这里的readInterestOp是用int来表示的。