自己基于Netty实现了一个通信框架,给它起名叫Caviar(https://github.com/mailzyw/caviar)。下面给出框架介绍。
一、功能设计
提供了两个通信相关的接口Client和Server
1、网络客户端Client
Client接口提供建连、登录、登出、发送请求消息(同步)、发送请求消息(异步回调)、接收服务端请求消息等功能。
public interface Client {
/**
* 连接服务端
* @param host host
* @param port port
*/
void connect(String host, int port) throws CaviarNetworkException;
/**
* 关闭客户端
* @throws IOException
*/
void close() throws IOException;
/**
* 重连服务端
*/
void reconnect();
/**
* 设置客户端运行状态
* @param running running
*/
void setRunningState(boolean running);
/**
* 客户端登录
* @param loginMsg loginMsg
* @return 登录响应
*/
byte[] login(byte[] loginMsg) throws CaviarNetworkException;
/**
* 客户端登出
* @param logoutMsg logoutMsg
* @return
*/
byte[] logout(byte[] logoutMsg) throws CaviarNetworkException;
/**
* 发送消息——同步
* @param msg msg
* @throws CaviarNetworkException
*/
byte[] sendMsgSync(byte[] msg) throws CaviarNetworkException;
/**
* 发送消息——异步
* @param msg msg
* @throws CaviarNetworkException
*/
void sendMsgAsync(byte[] msg, CaviarMsgCallback caviarMsgCallback);
}
CaviarServer为Client接口的实现类,提供CaviarServer(long timeout, CaviarServerBizListener caviarBizListener)构造方法。
2、网络服务端Server
Server接口提供bind方法和close方法。bind方法用于绑定对应服务端口并开始监听客户端连接请求,close方法为服务端关闭操作。
public interface Server {
/**
* 启动操作
* @param port 监听端口
*/
void bind(int port) throws CaviarNetworkException;
/**
* 关闭操作
* @throws IOException
*/
void close() throws IOException;
}
CaviarServer为Server接口的实现类,提供CaviarServer(long timeout, CaviarServerBizListener caviarBizListener)构造方法。
3、请求消息处理器CaviarServerBizListener/CaviarServerBizListener
服务端和客户端的请求消息处理器,定义了处理请求消息的方法。
使用者通过实现这两个接口完成对消息处理的具体业务逻辑。
public interface CaviarServerBizListener {
/**
* 处理客户端登录请求
*/
void processClientLogin(RequestContext requestContext, SessionContext sessionContext, byte[] msg);
/**
* 处理客户端登出请求
*/
void processClientLogout(RequestContext requestContext, SessionContext sessionContext, byte[] msg);
/**
* 处理客户端请求消息
*/
void processClientMsg(RequestContext requestContext, SessionContext sessionContext, byte[] msg);
}
public interface CaviarClientBizListener {
/**
* 处理服务端请求消息
*/
void processServerMsg(RequestContext requestContext, SessionContext sessionContext, byte[] msg);
}
4、连接上下文SessionContext
用于标识一个网络连接(客户端与服务端),内部维护了网络连接信息Channel,并提供了向当前连接发送请求/响应消息等接口功能。使用者使用该接口完成请求消息的发送和响应。
NettySessionContext为SessionContext的具体实现。
5、请求上下文RequestContext
用于标识一次请求,内部维护了请求唯一标识、请求消息、响应消息、响应异步回调接收器等信息。在进行请求应答时会用到,使用者一般不需要直接操作。
二、协议设计
1、消息协议
Long address 消息发送端IP转换为的Long
Integer crcCode 版本号
Integer msgType 消息类型
Integer codeType 消息体序列化方式(0:json,1:xml)
Integer length 消息体长度
byte[] body 消息体
- 消息体定义为byte[]数组,留给使用者充分的实现自由。
- 使用者可以定义自己个性化实现方式的消息体,最后只需要将其序列化成byte[]进行网络传输即可
- codec包中提供了默认的序列化Gson实现类GsonSerialization,使用者可以基于此实现业务消息体的序列化和反序列化,当然也可以使用其他的序列化方式。
2、消息类型
|-请求消息
|-CLIENT_LOGIN_REQ(1001), //客户端登录
|-CLIENT_LOGOUT_REQ(1002), //客户端登出
|-CLIENT_MSG_SEND_REQ(1003), //客户端请求——同步
|-CLIENT_MSG_SEND_ASYNC_REQ(1004), //客户端请求——异步回调
|-SERVER_MSG_SEND_REQ(1013), //服务端请求——同步
|-SERVER_MSG_SEND_ASYNC_REQ(1014), //服务端请求——异步回调
|-响应消息
|-CLIENT_LOGIN_RESP(2001), //客户端登录
|-CLIENT_LOGOUT_RESP(2002), //客户端登出
|-CLIENT_MSG_SEND_RESP(2003), //客户端请求
|-心跳消息
|-PING(9001), //客户端Ping
|-PONG(9002), //服务端Pong
三、可靠性设计
1、客户端连接/请求超时功能:
- Client接口提供出来的connect/sendMsgSync/sendMsgAsync方法均支持超时时间的设置,超时时间为CaviarServer(long timeout, CaviarServerBizListener caviarBizListener)构造方法的timeout字段。
- 当客户端连接/请求超时时,将抛出CaviarNetworkException进行提示。
2、客户端断连重连:
- 客户端Client监测到网络断连事件后,会自动进入重连逻辑,每2秒进行一次重连操作,直到重连成功。
3、心跳检测:
- 当没有业务消息交互时,客户端与服务端之间会自动以5秒/次的频率进行心跳请求响应交互。
- 当客户端与服务端网络存在故障时,会导致心跳包交互超时,服务端会自动断连对应的客户端连接。
4、客户端重复登录保护:
- 该功能与业务紧密相关,开放给使用者按需自行实现。
5、消息缓存重发
- 该功能与业务紧密相关,开放给使用者按需自行实现。
- Caviar框架提供了完善的请求/响应消息收发接口,使用者可以基于这些接口实现业务层的消息接收确认及缓存重发。
四、性能设计
1、IO模型
Caviar框架底层基于Netty实现,继承了Netty提供的非阻塞IO模型
- 底层基于Selector的多路复用IO模型,实现非阻塞IO通信,使网络连接与IO线程解耦,具有高性能和高扩展性。
- 进行IO读写时,Netty采用DirectByteBuffer存储数据,同时引入了Buffer池,以此减少内存数据拷贝,提高IO性能。
2、线程模型
Caviar框架底层基于Netty实现,基础了Netty的Reactor线程模型
- 专门的NIO线程Acceptor负责监听服务端,接收客户端的TCP连接请求。
- IO读写事件由专门的NIO线程池负责。
- 无锁化的串行设计,一个NIO线程可以同时处理多条通信链路,但一条通信链路内的IO事件只由一个NIO线程处理,从而避免多线程切换的锁问题。
- 将IO事件解析为业务消息后,交由Caviar的业务分发器处理,业务处理逻辑在专门的业务线程池中进行执行,不影响NIO线程。
3、序列化框架
- Caviar消息协议直接基于byte数组进行序列化与反序列化,简单高效。
- 业务消息体直接定义为byte数组,将编解码操作开放给使用者自行实现。
4、同步/异步请求线程模型
同步请求线程模型 异步请求线程模型五、使用示例
caviar框架源码中的demo包中提供了一个简单的使用示例。
- CaviarServerBootstrap为服务端的启动器,它完成了服务端构造及bind操作
- CaviarClientBootstrap为客户端的启动器,它完成了客户端的构造及连接、登录、发送请求等操作
- CaviarClientBizListenerDefaultImp和CaviarServerBizListenerDefaultImp为请求消息处理器的业务实现类,demo里面只是做了简单的操作。
网友评论