Skip to content

网络层

本文档描述 Zeze 基于 JDK NIO 自研的轻量异步网络层(仅 WebSocket 子模块使用 Netty),包括 Service 抽象、Protocol 编码格式、Rpc 模型、连接管理、握手加密压缩、WebSocket 支持与协议派发流程,供网络通信开发检索参考。

Zeze 的核心 TCP 网络层并非基于 Netty,而是用 JDK 原生 java.nio.channels.Selector 自研的事件驱动 IO 线程(Zeze.Net.Selector 继承自 Thread):发送不阻塞,接收解码为协议对象后派发到线程池。只有 WebSocket 子模块Websocket / WebsocketHandle)引入了 Netty。

Zeze.Net.Service 是所有网络服务的抽象基类。

组成说明
连接管理socketMapLongConcurrentHashMap<AsyncSocket>),按 sessionId 索引
协议注册派发ProtocolFactoryHandle 注册工厂与处理器,收到数据按 typeId 查找派发
配置管理SocketOptions + ServiceConf
生命周期start() / stop()

重载事件方法时必须调用基类实现

事件方法说明
OnSocketAccept接受新连接(可检查最大连接)
OnSocketConnected客户端连接成功,加入 socketMap
OnSocketClose关闭,移除
OnHandshakeDone握手完成,通知 Connector
OnSocketProcessInputBuffer接收数据,可自定义协议解析

Zeze.Net.Protocol<TArgument> 是所有协议的基类,包含 Argument(Bean)。

Header = ModuleId[4] + ProtocolId[4] + Size[4]
Payload = FamilyClass[1] + [ResultCode[8]] + EncodedArgument
概念公式 / 说明
TypeId(long)moduleId << 32 | protocolId,全局唯一
ResultCode非 0 才编码(BitResultCode 标志位)
注册Protocol.register(typeId, class)
级别说明
eCriticalPlus0最高
eCritical1
eNormal2默认
eSheddable3可丢弃

负载高时按优先级丢低级别。

p.Send(asyncSocket); // 指定连接
p.Send(service); // 使用第一个连接

协议层和数据库共享的 Bean 按事务模式实现,容器性能差(如 BSend 历史上 SetList 优化)。可手动优化:

// 自定义 Bean
public class MyBean extends Bean { /* ... */ }
// 自定义协议
public class MyProtocol extends Protocol<MyBean> { /* ... */ }
// 框架注册后,删除旧的 ProtocolFactoryHandle,注册自己的

Zeze.Net.Rpc<TArgument, TResult> 继承 Protocol,增加 ResultsessionId

Header
Payload = FamilyClass[1] + [ResultCode[8]] + SessionId[8] + ArgumentOrResult
FamilyClass说明
Request1请求
Response0响应
方式接口说明
异步回调rpc.Send(socket, (response) -> {...}, 5000)超时 5000ms
同步等待rpc.SendForWait(socket, 5000) + future.await() + rpc.getResultCode()阻塞等待
发送响应rpc.SendResult() / SendResultCode(0)成功
带结果响应setResultCode(0) + Result.setYyy + SendResult设置结果后发送

rpcContexts 映射:发请求时注册上下文并启动定时器,超时 isTimeout = trueresultCode = Procedure.Timeout

配置说明
具体地址指定 IP/Port
@internal内网
@external外网
<Acceptor Ip="@internal" Port="5555"/>
特性说明
自动重连isAutoReconnect,指数退避,初始 1 秒,最大 maxReconnectDelay
握手就绪GetReadySocket / TryGetReadySocket
自定义子类class 配置
new Connector("127.0.0.1", 5555, true); // 自动重连
connector.setMaxReconnectDelay(30_000);

支持 TCP 和 WebSocket。

抽象基类。

接口 / 属性说明
Send(Protocol) / Send(ByteBuffer) / Send(Binary) / Send(byte[])发送
UserState附加任意状态
recvCount / sendSize统计
activeRecvTime / activeSendTime活跃时间,KeepAlive 检测
isHandshakeDone握手是否完成
Type 枚举eServer / eClient / eServerSocket

HandshakeBase 及子类 HandshakeServer / HandshakeClient

eEncryptType说明
Disable0不加密
Aes1AES + DH(依赖 IP)
AesNoSecureIp2AES(不依赖 IP)
RsaAes3RSA + AES
eCompressType说明
Disable0不压缩
Mppc1Mppc
Zstd2Zstd
SHandshake0 (支持加密压缩)
CHandshake (选择)
SHandshake (加密参数)
CHandshakeDone

握手协议在 IO 线程同步执行,DispatchMode.Direct

Zeze.Net.Websocket / WebsocketClient

new Connector(true, "ws://127.0.0.1:8080/ws");

与 TCP 透明,共享 Service 事件。

Zeze.Services.Handshake.KeyExchange 提供独立的 RSA + AES 密钥交换 RPC,支持双向认证。

keyExchange.send(socket, clientPrivateKey);
KeyExchange.addHandler(service, serverPrivateKey);
选项默认值说明
inputBufferMaxProtocolSize2M输入缓冲最大协议大小
outputBufferMaxSize2M输出缓冲最大大小
noDelay-TCP NoDelay
sendBuffer-发送缓冲
receiveBuffer-接收缓冲
closeWhenMissHandlefalse找不到处理器时是否关闭连接
AsyncSocket 接收
解密解压
Service.OnSocketProcessInputBuffer
Protocol.decode
dispatchUnknownProtocol / dispatchProtocol
├─ 握手:IO 线程同步执行
├─ 事务:创建 Procedure,提交线程池
└─ 非事务:直接提交线程池
JVM 参数作用
-DprotocolLog=DEBUG开启协议日志
-DprotocolLogExcept=TypeId排除指定 TypeId

日志格式:SEND / RECV / Send / Broc / Recv + sessionId + 协议名。

Linkd 建议排除 DispatchSend 的 TypeId,只输出包装的协议。

<ServiceConf>
<Acceptor Ip="@internal" Port="5555"/>
<Acceptor Ip="@external" Port="5556"/>
<Connector Ip="127.0.0.1" Port="5001" AutoReconnect="true"/>
</ServiceConf>

Acceptor 和 Connector 可在同一 ServiceConf 中共存。