常规通讯
ISender、IReceiver、Listener、Channel 和 IPacketizer 常规通讯抽象。
常规通讯抽象把“如何发送、如何接收、如何监听、如何关闭通道、如何打包拆包”拆成几组小接口。核心框架只定义协议边界,具体网络连接、消息队列连接、事件通道等实现由 Zongsoft.Net、Zongsoft.Messaging.* 或其它扩展项目承接。
类型关系
ISender
发送字节数据。
ISender<T>
发送强类型数据包。
IReceiver
接收 ReadOnlySequence<byte> 源码 字节序列。
IListener<T>
监听并处理强类型通讯包。
ListenerBase<T>
监听器基类,实现接收、拆包和交给处理器的流程。
IChannel
可关闭、可异步释放的通讯通道。
ChannelBase
通道基类,统一关闭状态、关闭事件和释放流程。
IChannelSelector<T>
根据键选择一个通道。
IPacketizer<TPackage>
强类型通讯包的打包和拆包接口。
IPacketizer<TRequest, TResponse>
请求/应答模式下的请求打包和响应拆包接口。
Channel 设计思想
Channel 是“通讯端点”的生命周期抽象,而不是某一种协议的代名词。它表达的是:这个端点是否关闭、如何关闭、关闭后如何通知外部,以及是否可以被选择器或管理器持有。
这个设计让不同通讯形态可以共享同一个生命周期词汇:
TCP 连接通道:
TcpChannelBase<T>继承ChannelBase,同时实现ISender和ISender<T>。事件通道:
IEventChannel继承IChannel和ISender<EventContext>,可把事件发送到远端。消息队列通道:
ZeroQueueEventChannel继承ChannelBase,把事件编码后投递到 ZeroMQ 队列。消息消费者:
MessageConsumerBase<TQueue>继承ChannelBase,把订阅生命周期也纳入通道关闭模型。
接收与拆包
ListenerBase<T> 实现了从字节到强类型包的模板流程:收到字节序列后调用 IPacketizer<T>.Unpack,拆包成功后再调用处理器。
来源:framework/Zongsoft.Core/src/Communication/ListenerBase.cs(节选;上下文见源文件)。
IPacketizer<T> 适合处理粘包、半包、长度头、压缩、加密和自定义二进制协议。它的 Unpack 接收 ref ReadOnlySequence<byte>,实现者可以在拆出一个包后推进序列,让上层继续处理缓冲区中的后续包。
来源:framework/Zongsoft.Core/src/Communication/IPacketizer.cs(节选;上下文见源文件)。
Zongsoft.Net 中的实现
Zongsoft.Net 把这些抽象落到 TCP 网络通讯上:
TcpServer<T>继承ListenerBase<T>,持有IPacketizer<T>,负责监听并创建 TCP 通道。TcpChannelBase<T>继承ChannelBase,负责单连接的发送、接收、打包、拆包和关闭。TcpServerChannelManager<T>维护服务端通道集合,并在客户端连接时创建通道。Packetizer提供无头包和长度头包两种基础拆包实现。
来源:framework/Zongsoft.Net/samples/server/Program.cs(节选;上下文见源文件)。
上面来自 framework 的 TCP 服务端样例;Handler 是同一 Program.cs 的内部类型,接收文本后广播 ACK 回复。Discussions 没有直接托管 TCP 通道。配套客户端、启动参数和关闭行为见网络通讯。
现实场景
通道模型适合任何“有打开/关闭生命周期,并可发送或接收数据”的场景。网络连接只是其中一种;事件总线、消息队列订阅、设备连接、网关会话也可以成为通道。
相关资源
最后更新于