Netty随笔1

Netty Server监听用的是, NioServerSocketChannel, 客户端链接用的是NioSocketChannel。继承关系如下

AbstractNioChannel 

-> AbstractNioMessageChannel -> ... NioServerSocketChannel

-> AbstractNioByteChannel -> NioSocketChannel

这两个Channel的基类,一个是AbstractNioMessageChannel就是已经将byte流解析为一个List<Object>, 而另一个AbstractNioByteChannel则是直接将Byte数组传递过去。

NioServerSocketChannel 中,每当新建一个链接,其实都是在Read方法中,生成一个新的NioSocketChannel。所以其实NioServerSocketChannel只是负责监听的Channel,具体到每一个链接,仍然是NioSocketChannel。

如果我们想要控制服务器的链接数量,完全可以在NioServerSocketChannel的doReadMessages里面做些文章

    @Override

    protected int doReadMessages(List<Object> buf) throws Exception {

        int result = super.doReadMessages(buf);

        if (result > 0) {

            //success, 这里已经将byte数组转化为一个List<Object>,并且唯一的成员就是新建的链接

            NioSocketChannel channel = (NioSocketChannel) buf.get(0);

            .....

            if (拒绝链接) {

                channel.close();

                return 0;

            }

       }

        return result; 

}

而ByteToMessageDecoder, 通常是我们的协议实现层,会将byte数组转化为一个List<Object>, 然后调用read方法直接对Object进行处理,每个Object,都会调用一次read方法。

由于可能多次read, 读取多个byte才能生成一个List<Object>, 所以并不是read方法每次读取都会被调用,因此使用ByteToMessageDecoder我们会观察到readComplete被调用(每次读取字节都会触发readComplete),但是read没有被调用的情形。

但是AbstractNioMessageChannel在这一点上与Decoder不同,这个Channel中,会在生成List<Object>之后,针对每个Object做循环调用,这一点与ByteToMessageDecoder相同,但是循环调用read之后,才会调用一次readComplete,这一点不同。此时readComplete的触发更为稀少。

















你可能感兴趣的:(Netty随笔1)