文档章节

nio服务端序列图

泡海椒
 泡海椒
发布于 2016/02/17 11:07
字数 616
阅读 32
收藏 4

NIO服务端通信序列图如下:

下面,我们对NIO服务端的主要创建过程进行讲解和说明:

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

?

1
ServerSocketChannel acceptorSvr = ServerSocketChannel.open();

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

?

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

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

?

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

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

?

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

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

?

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

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

?

1
SocketChannel channel = svrChannel.accept();

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

?

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

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

?

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

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

?

1
int  readNumber = channel.read(recelvedBuffer);

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

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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方法,将消息异步发送给客户端,示例代码如下:

?

1
socketChannel.write(buffer);

注意:如果发送区TCP缓冲区满,会导致写半包,此时,需要注册监听写操作位,循环写,直到整包消息写入TCP缓冲区。


© 著作权归作者所有

共有 人打赏支持
泡海椒
粉丝 10
博文 279
码字总数 291526
作品 0
成都
程序员
Netty高性能之道

背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨节点远程服务调用。相比于传统基于J...

HenrySun
2016/04/19
119
0
Java异步NIO框架Netty实现高性能高并发

背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨节点远程服务调用。相比于传统基于J...

java知识分子
09/28
0
0
Java 与 Netty 实现高性能高并发

1. 背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨节点远程服务调用。相比于传统基于...

ljianbing
2017/04/01
0
0
Netty系列之Netty高性能之道

背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨节点远程服务调用。相比于传统基于J...

宇智波带土
2014/06/17
0
1
Spring+Netty+Protostuff+ZooKeeper实现轻量级RPC服务

RPC简介 RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样。 RPC 可基于 HTTP 或 TCP 协议,Web Service 就是基于 HTTP 协...

Listen_ing
2016/05/26
2.3K
12

没有更多内容

加载失败,请刷新页面

加载更多

Android适配相关

Android 6.0、7.0、8.0、9.0适配 关于android适配的好文章 Android权限申请库 AndPermission 国产,有中文文档,链式调用,用起来简单 easypermissions 谷歌官方出品 PermissionsDispatcher ...

Skqing
7分钟前
1
0
Google推出了以隐私和安全为中心的变更

作为Google Play开发者政策更新的一部分,Google推出了以隐私和安全为中心的变更。 在旨在保护敏感数据的行动中,有针对请求短信和呼叫记录权限的应用程序的新规则。 即日起,只有配置为默认...

问题终结者
10分钟前
0
0
Kotlin个人理解入门篇

了解kotlin并开始使用其做开发,是从最近之前做的项目开始之初,用的是kotlin,发现kotlin是一个特简洁,很多语法糖提供使用,可以提高开发效率的语言。谷歌在2017年谷歌大会正式宣布支持and...

DannyCoder
15分钟前
0
0
springboot+rabbitmq整合

1.安装好rabbitmq 2.新建一个springBoot项目:rabbitmq_demo 3.添加pom依赖: <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifact......

狼王黄师傅
22分钟前
0
0
使用JDK自带的jmap和jhat监控处于运行状态的Java进程

对于处于运行状态中的Java进程,JDK自带了很多工具,允许Java开发人员监控运行进程中的各种状态,比如该进程内部创建了多少个对象实例,消耗了多少内存,等等。 本文基于JDK1.8而写成。 我下...

JerryWang_SAP
32分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部