《Netty 权威指南》—— 服务端序列图

    xiaoxiao2024-02-21  145

    声明:本文是《Netty 权威指南》的样章,感谢博文视点授权并发编程网站发布样章,禁止以任何形式转载此文。

    下面,我们对NIO服务端的主要创建过程进行讲解和说明,作为NIO的基础入门,我们将忽略掉一些在生产环境中部署所需要的一些特性和功能。

    步骤一:打开ServerSocketChannel,用于监听客户端的连接,它是所有客户端连接的父管道,代码示例如下:

    1ServerSocketChannel acceptorSvr = ServerSocketChannel.open();

    步骤二:绑定监听端口,设置连接为非阻塞模式,示例代码如下:

    1 acceptorSvr.socket().bind(new InetSocketAddress(InetAddress.getByName(“IP”), port)); 2 acceptorSvr.configureBlocking(false);

    步骤三:创建Reactor线程,创建多路复用器并启动线程,代码如下:

    1Selector selector = Selector.open(); 2 New Thread(new ReactorTask()).start();

    步骤四:将ServerSocketChannel注册到Reactor线程的多路复用器Selector上,监听ACCEPT事件,代码如下:

    1SelectionKey key = acceptorSvr.register( selector, SelectionKey.OP_ACCEPT, ioHandler);

    步骤五:多路复用器在线程run方法的无限循环体内轮询准备就绪的Key,代码如下:

    1 int num = selector.select(); 2Set selectedKeys = selector.selectedKeys(); 3Iterator it = selectedKeys.iterator(); 4 while (it.hasNext()) { 5      SelectionKey key = (SelectionKey)it.next(); 6      // ... deal with I/O event ... 7}

    步骤六:多路复用器监听到有新的客户端接入,处理新的接入请求,完成TCP三次握手,建立物理链路,代码示例如下:

    1SocketChannel channel = svrChannel.accept();

    步骤七:设置客户端链路为非阻塞模式,示例代码如下:

    1 channel.configureBlocking(false); 2 channel.socket().setReuseAddress(true);

    步骤八:将新接入的客户端连接注册到Reactor线程的多路复用器上,监听读操作,用来读取客户端发送的网络消息,代码如下:

    1SelectionKey key = socketChannel.register( selector, SelectionKey.OP_READ, ioHandler);

    步骤九:异步读取客户端请求消息到缓冲区,示例代码如下:

    1 int  readNumber =  channel.read(receivedBuffer);

    步骤十:对ByteBuffer进行编解码,如果有半包消息指针reset,继续读取后续的报文,将解码成功的消息封装成Task,投递到业务线程池中,进行业务逻辑编排,示例代码如下:

    01 Object message = null; 02 while(buffer.hasRemain()) 03{ 04        byteBuffer.mark(); 05        Object message = decode(byteBuffer); 06        if (message == null) 07        { 08           byteBuffer.reset(); 09           break; 10        } 11        messageList.add(message ); 12} 13 if (!byteBuffer.hasRemain()) 14byteBuffer.clear(); 15else 16     byteBuffer.compact(); 17 if (messageList != null & !messageList.isEmpty()) 18{ 19 for(Object messageE : messageList) 20    handlerTask(messageE); 21}

    步骤十一:将POJO对象encode成ByteBuffer,调用SocketChannel的异步write接口,将消息异步发送给客户端,示例代码如下:

    1socketChannel.write(buffer);

    注意:如果发送区TCP缓冲区满,会导致写半包,此时,需要注册监听写操作位,循环写,直到整包消息写入TCP缓冲区,此处不赘述,后续Netty源码分析章节会详细分析Netty的处理策略。 当我们了解创建NIO服务端的基本步骤之后,下面我们将前面的时间服务器程序通过NIO重写一遍,让大家能够学习到完整版的NIO服务端创建。

    NIO服务端通信序列图

    原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: 《Netty 权威指南》—— 服务端序列图

    文章转自 并发编程网-ifeve.com

    相关资源:敏捷开发V1.0.pptx
    最新回复(0)