-
Notifications
You must be signed in to change notification settings - Fork 68
AIO NIO异步通信框架使用指南
###一、类说明
- 网络通信架构图
- 网络通信集类
######AIO 网络通信类和 NIO 网络通信类均继承自这个socket连接上下文基类
类路径 | 说明 |
---|---|
org.voovan.network.SocketContext | socket连接上下文 |
- AIO网络通信类
类路径 | 说明 |
---|---|
org.voovan.network.aio.AioServerSocket | Aio Socket 服务端类,继承自socket连接上下文类 |
org.voovan.network.aio.AioSocket | Aio Socket 客户端类,继承自socket连接上下文类 |
org.voovan.network.aio.AioSession | Aio Socket 会话类 |
- NIO网络通信类
类路径 | 说明 |
---|---|
org.voovan.network.nio.NioServerSocket | Nio Socket 服务端类,继承socket连接上下文类 |
org.voovan.network.nio.NioSocket | Nio Socket 客户端类,继承socket连接上下文类 |
org.voovan.network.nio.NioSession | Nio Socket 会话类 |
- 过滤器接口 #####解决消息编码和解码问题
类路径 | 说明 |
---|---|
org.voovan.network.IoFilter | Socket 通信过滤器类 |
- 消息截断接口 #####解决 Socket 粘包的问题
类路径 | 说明 |
---|---|
org.voovan.network.MessageSplitter | Socket 消息截断类 |
###二、类方法说明
####2.1 网络通信类使用说明
######由于基于 AIO 和 NIO 通信的服务端类、客户端类、会话类暴露的方法都是相同,这里就只作一次说明,以下代码中*
可以使用 A 和 N,分别代表 AioServerSocket 和 NioServerSocket。以下其他类似函数中*
号的使用是类似的。
#####2.1.1 Socket连接上下文类
org.voovan.network.SocketContext
######在以下2.1.2和2.1.3中讲解的类均继承于这个基类
public SocketContext(String host,int port,int readTimeout)
- 构造一个Socket服务端类。
- host: 服务发布地址。
- port: 服务发布端口。
- readTimeout: 读取超时时间。
public Chain<IoFilter> filterChain()
- 获取过滤器链。
- 返回值: 过滤器链,可以通过这个过滤器链来管理过滤器。
public IoHandler handler()
- 获取业务处理句柄。
- 返回值: 业务处理句柄。
public void handler(IoHandler handler)
- 设置消息粘包分割器。
- handler: 消息粘包分割器。
public MessageSplitter messageSplitter()
- 获取消息粘包分割器。
- 返回值: 消息粘包分割器。
public void messageSplitter(MessageSplitter messageSplitter)
- 设置业务处理句柄。
- handler: 业务处理句柄。
public ConnectModel getConnectModel()
- 获取连接模式。
- 返回值: 连接模式
- ConnectModel.SERVER: 服务模式,这个连接由 SocketServer 的 Accept 发起的连接。
- ConnectModel.CLIENT: 客户端模式,这个连接由 SocketClient 直接发起的连接。
public String getHost()
- 获取当前Host地址。
- 返回值: 当前Host地址。
public int getPort()
- 获取当前Port端口号。
- 返回值: 当前Port端口号。
public int getReadTimeout()
- 获取当前超时时间。
- 返回值: 当前超时时间。
#####2.1.2 服务端类
org.voovan.network.aio.AioServerSocket
org.voovan.network.nio.NioServerSocket
public *ioServerSocket(String host,int port,int readTimeout) throws IOException
- 构造一个Socket服务端类。
- host: 服务发布地址。
- port: 服务发布端口。
- readTimeout: 读取超时时间。
public boolean isConnect()
- 判断当前 Socket 连接是否处于连接状态。
- 返回值: true:处于连接状态,false:连接处于断开状态。
public boolean Close()
- 关闭当前 Socket 连接。
- 返回值: true:连接成功关闭,false:连接关闭失败。
public void start() throws IOException
- 启动当前服务连接,时当前处于服务可用状态。
#####2.1.3 客户端类
org.voovan.network.aio.AioSocket
org.voovan.network.nio.NioSocket
public *ioSocket(String host, int port, int readTimeout) throws IOException
- 构造一个Socket客户端类。
- host: 服务发布地址。
- port: 服务发布端口。
- readTimeout: 读取超时时间。
public * socketChannel()
- 获取 SocketChannel 对象, "*"代表返回值类型。
- 返回值: 获取当前 java 异步通信类,Aio 通信返回AsynchronousSocketChannel,Nio 通信返回SocketChannel。
public AioSession getSession()
- 获取 Session 会话对象。
- readTimeout: 读取超时时间。
public boolean isConnect()
- 判断当前 Socket 连接是否处于连接状态。
- 返回值: true:处于连接状态,false:连接处于断开状态。
public boolean Close()
- 关闭当前 Socket 连接。
- 返回值: true:连接成功关闭,false:连接关闭失败。
public void start() throws Exception
- 启动当前服务连接,时当前处于服务可用状态。
#####2.1.4 Socket会话类
org.voovan.network.aio.AioSession
org.voovan.network.nio.NioSession
######用于缓冲会话中的各种对象和会话属性。
public SocketContext sockContext()
- 获取socket连接上下文
- 返回值: socket连接上下文。
public boolean containAttribute(Object key)
- 判断是否包含某个会话属性
- ***key:***属性名称
public Object getAttribute(Object key)
- 获取会话属性值
- ***key:***属性名称
- ***返回值:***属性值
public void setAttribute(Object key, Object value)
- 设置会话属性值
- ***key:***属性名称
- ***value:***属性值
public void send(ByteBuffer buffer) throws IOException
- 发送消息
- buffer: 发送消息的缓冲区,注意直接调用不会出发 onSent 事件。
public abstract boolean close();
- 关闭当前 Socket 连接,不会出发 onClose 事件
#####2.1.5 过滤器接口
org.voovan.network.IoFilter
######解决消息编码和解码问题,用于再接受前或者发送后将消息发送到Socket缓冲区。
public Object decode(IoSession session,Object object)
- 过滤器解密函数,接收事件(onRecive)前调用。
- session: Socket 会话对象。
- object: 缓冲区接收到的对象,如果是第一个过滤器是Bytebuffer。
public Object encode(IoSession session,Object object)
- 过滤器加密函数,发送事件(onSend)后调用。
- session: Socket 会话对象。
- object: 发送到缓冲区的对象,如果是第一个过滤器是onRecive返回的对象。
#####2.1.6 消息分割判断类
org.voovan.network.MessageSplitter
######判断消息是否可分割,用于截断消息,解决消息粘包的问题(代码中包含 HTTP协议,字符串换行,定长报文的粘包实现)。
消息粘包有两种截断方式:
- 1.消息截断器生效,则返回报文。
- 2.消息读取时间超时,例如设置5s,则连续5秒内没有读取到有用的消息则返回报文。
public boolean canSplite(IoSession session,byte[] buffer,int elapsedtime);
- 过滤器解密函数,接收事件(onRecive)前调用。
- session: Socket 会话对象。
- buffer: 缓冲区接收到的字节数组。
- elapsedtime: 从第一次接收到现在用时(单位:millisSecond)。
###三、使用举例 ######这里使用AIO举例,NIO的例子使用类似于 AIO 的列子 #####3.1 过滤器类使用举例
package org.voovan.network.messagesplitter;
import org.voovan.network.IoSession;
import org.voovan.network.messagesplitter;
/**
* 按换行对消息分割
*
* @author helyho
*
*/
public class LineMessageSplitter implements MessageSplitter {
@Override
public boolean canSplite(IoSession session, byte[] buffer, int elapsedtime) {
//遍历每个字节,查找到换行符则返回true标识可以分割.
for(int i=0;i<buffer.length;i++){
if(buffer[i]=='\r' || buffer[i]=='\n'){
return true;
}
}
return false;
}
}
#####3.2 业务处理句柄使用举例
package org.voovan.test.network;
import java.nio.ByteBuffer;
import org.voovan.network.IoHandler;
import org.voovan.network.IoSession;
import org.voovan.network.MessageLoader;
import org.voovan.tools.log.Logger;
/**
*客户端业务句柄类
**/
public class ClientHandlerTest implements IoHandler {
//连接事件
@Override
public Object onConnect(IoSession session) {
Logger.simple("onConnect"); //在日志平台,输出事件名称
session.setAttribute("key", "attribute value"); //再会话中保存属性
String msg = new String("test message"); //组装一个消息
return msg; //返回消息,在 onConnect 事件发送消息
}
//连接断开事件
@Override
public void onDisconnect(IoSession session) {
Logger.simple("onDisconnect"); //在日志平台,输出事件名称
}
//连接接收事件
@Override
public Object onReceive(IoSession session, Object obj) {
Logger.simple("onRecive: "+obj.toString()); //在日志平台,输出事件名称和接受到的消息内容
Logger.simple("Attribute onRecive: "+session.getAttribute("key")); //输出会话中保存的属性
session.close(); //关闭 Socket 连接
return obj;
}
//异常事件
@Override
public void onException(IoSession session, Exception e) {
Logger.simple("onException"); //在日志平台,输出事件名称和接受到的消息内容
e.printStackTrace(); //输入异常栈信息
}
//消息发送事件
@Override
public void onSent(IoSession session, Object obj) {
ByteBuffer sad = (ByteBuffer)obj; //byte缓冲区
sad = (ByteBuffer)sad.rewind(); //byte缓冲区位置重置
Logger.simple("onSent: "+MessageLoader.byteBufferToString(sad)); //输出事件名称和发送的消息内容
}
}
#####3.3 服务端类使用举例
package org.voovan.test.network.aio;
import java.io.IOException;
import org.voovan.network.aio.AioServerSocket;
import org.voovan.network.filter.StringFilter;
import org.voovan.test.network.ServerHandlerTest;
public class AioServerSocketTest {
public static void main(String[] args) throws IOException {
AioServerSocket serverSocket = new AioServerSocket("127.0.0.1",2031,1); //构造服务端类实例
serverSocket.handler(new ServerHandlerTest()); //设置业务处理句柄
serverSocket.filterChain().add(new StringFilter()); //设置消息过滤器
serverSocket.start(); //启动服务类
}
}
#####3.3 客户端类使用举例
package org.voovan.test.network.aio;
import org.voovan.network.aio.AioSocket;
import org.voovan.network.filter.StringFilter;
import org.voovan.test.network.ClientHandlerTest;
import org.voovan.tools.log.Logger;
public class AioSocketTest {
public static void main(String[] args) throws Exception {
AioSocket socket = new AioSocket("127.0.0.1",2031,100); //构造客户端类实例
socket.handler(new ClientHandlerTest()); //设置业务处理句柄
socket.filterChain().add(new StringFilter()); //设置消息过滤器
socket.start(); //启动服务类
}
}