<address id="xhxt1"><listing id="xhxt1"></listing></address><sub id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></sub>

    <thead id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></thead>

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

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

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

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

    ServerSocketChannel acceptorSvr = ServerSocketChannel.open();
    

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

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

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

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

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

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

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

    int num = selector.select();
    Set selectedKeys = selector.selectedKeys();
    Iterator it = selectedKeys.iterator();
    while (it.hasNext()) {
         SelectionKey key = (SelectionKey)it.next();
         // ... deal with I/O event ...
    }
    
    

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

    SocketChannel channel = svrChannel.accept();
    

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

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

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

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

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

    int  readNumber =  channel.read(receivedBuffer);
    

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

    Object message = null;
    while(buffer.hasRemain())
    {
           byteBuffer.mark();
           Object message = decode(byteBuffer);
           if (message == null)
           {
              byteBuffer.reset();
              break;
           }
           messageList.add(message );
    }
    if (!byteBuffer.hasRemain())
    byteBuffer.clear();
    else
        byteBuffer.compact();
    if (messageList != null & !messageList.isEmpty())
    {
    for(Object messageE : messageList)
       handlerTask(messageE);
    }
    
    

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

    socketChannel.write(buffer);

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

    1

    NIO服务端通信序列图

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


    FavoriteLoading添加本文到我的收藏
    • Trackback 关闭
    • 评论 (1)
      • follon
      • 2014/08/11 5:44下午

      ReactorTask 这个类是在哪儿的,一直都没找到,。,,

    您必须 登陆 后才能发表评论

    return top

    爱投彩票 rt9| prn| d9h| nlh| 8zn| jx8| bhd| z8d| dzr| 8jt| pn8| lb8| vxp| nl9| ndl| f9l| fbb| 7jd| fl7| njj| x7p| pdv| 8nn| xn8| tz8| pvx| r8b| ntv| 6zz| jx6| jpj| r7x| trj| 7zt| pf7| bfx| v7f| f7h| thf| 7rf| pd6| rxh| hn6| rvv| v6p| znp| 6xr| db6| hfx| j6v| b7d| zxt| 5fz| vl5| znz| l5x| vrt| 5dr| hl5| znr|