🖧 CommunicationServiceAbstract 基类
CommunicationServiceAbstract<O, D> 是所有服务端通信传输实现的基类。它继承自 CoreUnify<O, D> 并实现 ICommunicationService。
public abstract class CommunicationServiceAbstract<O, D> : CoreUnify<O, D>, ICommunicationService
where O : class
where D : class
与 CommunicationAbstract 的区别
| 方面 | CommunicationAbstract (客户端) | CommunicationServiceAbstract (服务端) |
|---|---|---|
| 角色 | 主动连接远程端点 | 绑定端口,等待客户端连接 |
| 发送接口 | ISend / ISendWait |
ISendService |
| 数据发送 | 向单个远程端点发送 | 广播/组播/单播到已连接客户端 |
| 客户端管理 | 无 | ConcurrentDictionary 管理已连接客户端 |
| 移除客户端 | 无 | RemoveAsync(string[]) — 主动踢出指定客户端 |
| 自动重连 | 支持(TCP/WS/UDP) | 不需要(服务端被动接受连接) |
7个抽象方法
每个服务端通信实现必须实现全部 7 个方法:
1. OnAsync — 启动服务
public abstract Task<OperateResult> OnAsync(CancellationToken token = default);
绑定端口并开始监听客户端连接。对于 TCP 服务器,创建 TcpListener 并启动 Accept 循环;对于 WebSocket,启动 HttpListener 并处理升级请求。
2. OffAsync — 停止服务
public abstract Task<OperateResult> OffAsync(bool hardClose = false, CancellationToken token = default);
停止接受新连接并断开所有已连接客户端。hardClose = true 强制断开所有客户端。
3. SendAsync (广播) — 向多个客户端发送
public abstract Task<OperateResult> SendAsync(byte[] data, string[]? address = null, CancellationToken token = default);
向已连接的客户端发送数据。address = null 时群发所有客户端;指定地址数组时定向发送。
4. SendAsync (单播) — 向单个客户端发送
public abstract Task<OperateResult> SendAsync(byte[] data, string address, CancellationToken token = default);
向指定地址的单个客户端发送数据。
5. RemoveAsync — 移除客户端
public abstract Task<OperateResult> RemoveAsync(string[] address, CancellationToken token = default);
按 IP 地址/标识符主动断开指定客户端。可用于踢出异常客户端或实现访问控制。
6. GetBaseObjectAsync — 获取底层对象
public abstract Task<OperateResult> GetBaseObjectAsync(CancellationToken token = default);
返回底层服务端对象(如 TcpListener、HttpListener),用于高级场景。
7. GetStatusAsync — 服务状态
public abstract Task<OperateResult> GetStatusAsync(CancellationToken token = default);
返回服务端运行状态。通常检查监听器是否处于活动状态。
同步便捷方法
| 同步方法 | 委托的异步方法 |
|---|---|
On() |
OnAsync().GetAwaiter().GetResult() |
Off(bool hardClose = false) |
OffAsync(hardClose).GetAwaiter().GetResult() |
Send(byte[] data, string[]? address = null) |
SendAsync(data, address).GetAwaiter().GetResult() |
Send(byte[] data, string address) |
SendAsync(data, address).GetAwaiter().GetResult() |
Remove(string[] address) |
RemoveAsync(address).GetAwaiter().GetResult() |
GetBaseObject() |
GetBaseObjectAsync().GetAwaiter().GetResult() |
GetStatus() |
GetStatusAsync().GetAwaiter().GetResult() |
客户端事件通知
服务端通过 OnDataEvent 事件提供客户端连接/断开/消息通知。事件数据为 ClientMessage 类型,包含:
| 字段 | 类型 | 说明 |
|---|---|---|
Step |
Steps 枚举 |
客户端连接 / 客户端断开 / 消息接收 |
IpPort |
string |
客户端 IP 地址和端口 |
Bytes |
byte[]? |
接收到的消息数据 |
ClientId |
string |
WebSocket 客户端 ID(仅 WebSocket 服务端) |
通用配置模式
| 通用配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
SN |
string |
自动 GUID | 唯一实例标识符 |
IpAddress |
string? |
"127.0.0.1" |
监听地址 |
Port |
int |
6688 |
监听端口 |
Timeout |
int |
1000 |
I/O 超时(毫秒) |
MaxChunkSize |
int |
261120 |
每块最大字节数 |
RetrySendCount |
int |
5 |
每块重试次数 |
BufferSize |
int |
1048576 (1MB) |
接收缓冲区大小 |
数据流
客户端 1 (192.168.1.10:12345) ---+
客户端 2 (192.168.1.11:54321) ---+--> 服务端 (ICommunicationService)
客户端 3 (192.168.1.12:99999) ---+ |
+-- OnDataEvent (ClientMessage)
|
+-- SendAsync(data, null) → 群发所有客户端
+-- SendAsync(data, "addr1") → 定向发送单个客户端
+-- SendAsync(data, ["a1","a2"]) → 组播指定客户端
+-- RemoveAsync(["addr3"]) → 踢出客户端
Dispose 行为
public override void Dispose()
{
Off(true); // 强制停止服务,断开所有客户端
base.Dispose();
}
public override async ValueTask DisposeAsync()
{
await OffAsync(true).ConfigureAwait(false);
await base.DisposeAsync().ConfigureAwait(false);
}
具体实现 (3 个)
| 类 | 命名空间 | 传输方式 | 特点 |
|---|---|---|---|
TcpServiceOperate |
Snet.Core.communication.net.tcp.service |
TCP 服务器 | TcpListener、MaxNumber 最大连接数、ConcurrentDictionary 客户端管理 |
WsServiceOperate |
Snet.Core.communication.net.ws.service |
WebSocket 服务器 | HttpListener WebSocket 升级、ClientId 标识 |
UdpServiceOperate |
Snet.Core.communication.net.udp.unicast.service |
UDP 服务 | UdpClient 接收循环、自动发现客户端端点 |
使用示例
using Snet.Core.communication.net.tcp.service;
using static Snet.Core.communication.net.tcp.service.TcpServiceData;
// 1. 配置
var config = new Basics
{
IpAddress = "0.0.0.0", // 监听所有接口
Port = 6688,
MaxNumber = 1000 // 最大连接数
};
// 2. 获取单例
var server = await TcpServiceOperate.InstanceAsync(config);
// 3. 监听客户端事件(连接/断开/消息)
server.OnDataEvent += (sender, e) =>
{
if (e.ResultData is ClientMessage msg)
{
switch (msg.Step)
{
case Steps.客户端连接:
Console.WriteLine($"客户端连接: {msg.IpPort}"); break;
case Steps.客户端断开:
Console.WriteLine($"客户端断开: {msg.IpPort}"); break;
case Steps.消息接收:
Console.WriteLine($"来自 {msg.IpPort}: {msg.Bytes?.Length} 字节"); break;
}
}
};
// 4. 启动服务
await server.OnAsync();
// 5. 群发所有已连接客户端
await server.SendAsync(Encoding.UTF8.GetBytes("广播消息"));
// 6. 定向发送给单个客户端
await server.SendAsync(Encoding.UTF8.GetBytes("你好"), "192.168.1.10:12345");
// 7. 踢出指定客户端
await server.RemoveAsync(new[] { "192.168.1.10:12345" });
// 8. 停止服务
await server.OffAsync();
继承链
CoreUnify<O, D> — 单例、事件、计时、日志、语言
└── CommunicationServiceAbstract<O, D> — Send(广播/单播)/Remove(服务端通信)
├── TcpServiceOperate — TCP 服务器
├── WsServiceOperate — WebSocket 服务器
└── UdpServiceOperate — UDP 服务器
