通信层 - Snet Docs

Snet Framework -- 通信传输

概述

Snet Framework 提供 12 种通信传输类,覆盖 TCP、WebSocket、UDP、HTTP、串口和进程内通道。所有传输遵循统一的单例生命周期模式,并暴露一致的 API 用于连接、发送、接收和断开。

架构

                         +-- CoreUnify<O, D> --+
                         |  单例、事件系统      |
                         |  日志、多语言        |
                         +----------+----------+
                                    |
                  +-----------------+-----------------+
                  |                                   |
   CommunicationAbstract<O,D>           CommunicationServiceAbstract<O,D>
   (客户端传输)                        (服务端传输)
   - OnAsync / OffAsync                 - OnAsync / OffAsync
   - SendAsync / SendWaitAsync          - SendAsync (address)
   - GetStatusAsync                     - RemoveAsync
   - GetBaseObjectAsync                 - GetStatusAsync
                  |                                   |
   +--------------+--------------+         +----------+-----------+
   |              |              |         |                      |
TcpClient    WsClient     UdpClient   TcpService     WsService   UdpService
Serial       UdpMulticast  UdpBroadcast

继承层次

基类 用途 方法
CoreUnify<O, D> 单例、事件、日志、国际化 InstanceAsync()GetArgsAsync()、日志、语言
CommunicationAbstract<O, D> 客户端传输 OnAsyncOffAsyncSendAsyncSendWaitAsyncGetStatusAsyncGetBaseObjectAsync
CommunicationServiceAbstract<O, D> 服务端传输 OnAsyncOffAsyncSendAsync(address)RemoveAsyncGetStatusAsyncGetBaseObjectAsync

全部传输类

1. TCP 客户端 -- TcpClientOperate

继承: CommunicationAbstract<TcpClientOperate, TcpClientData.Basics>

命名空间: Snet.Core.communication.net.tcp.client

配置属性 类型 默认值 说明
IpAddress string "127.0.0.1" 远程服务器 IP
Port int 6688 远程服务器端口
InterruptReconnection bool true 断线自动重连
ReconnectionInterval int 1000 重连间隔(毫秒)
Timeout int 1000 I/O 超时(毫秒)
SendWaitInterval int 5000 发送等待读取超时(毫秒)
MaxChunkSize int 261120 每块最大字节数(255 KB)
RetrySendCount int 5 每块重试次数
BufferSize int 1048576 接收缓冲区(1 MB)
SN string 自动 GUID 唯一实例标识符

特性: 指数退避自动重连(500ms-30s)、分包发送带重试、单一读循环监控、SendWait 挂起/恢复模式。2026-08 重构起:SendAsync/SendWaitAsync 经实例内部请求锁串行化;新增 SetRawDataHandler(Func<ReadOnlyMemory<byte>, CancellationToken, ValueTask>? handler)——原始字节直接交付高频处理函数(跳过通用 OnDataEvent 载荷与语言消息构造;传 null 恢复通用路径)。

using Snet.Core.communication.net.tcp.client;
using static Snet.Core.communication.net.tcp.client.TcpClientData;

// 1. 创建配置
var config = new Basics
{
    IpAddress = "192.168.1.100",
    Port = 6688
};

// 2. 获取单例
var client = await TcpClientOperate.InstanceAsync(config);

// 3. 订阅接收数据事件
client.OnDataEvent += (sender, e) =>
{
    if (e.Status && e.ResultData is byte[] data)
        Console.WriteLine($"收到数据:{data.Length} 字节");
};

// 4. 连接
await client.OnAsync();

// 5. 发送
await client.SendAsync(Encoding.UTF8.GetBytes("你好 TCP!"));

// 6. 发送并等待响应
var result = await client.SendWaitAsync(
    Encoding.UTF8.GetBytes("PING"),
    CancellationToken.None);
if (result.Status)
    Console.WriteLine($"响应:{result.ResultData}");

// 7. 断开
await client.OffAsync();

2. TCP 服务端 -- TcpServiceOperate

继承: CommunicationServiceAbstract<TcpServiceOperate, TcpServiceData.Basics>

命名空间: Snet.Core.communication.net.tcp.service

配置属性 类型 默认值 说明
IpAddress string "127.0.0.1" 监听地址
Port int 6688 监听端口
MaxNumber int 1000 最大挂起连接数(backlog)
MaxChunkSize int 261120 每块最大字节数
RetrySendCount int 5 每块重试次数
Timeout int 1000 I/O 超时(毫秒)
BufferSize int 1048576 接收缓冲区(1 MB)

事件: ClientMessage 包含 Steps 枚举:客户端连接(Client Connected)/ 客户端断开(Client Disconnected)/ 消息接收(Message Received),以及 IpPortBytes

特性: ConcurrentDictionary 客户端管理、广播 + 定向发送、RemoveAsync 断开指定客户端。2026-08 重构起:每客户端发送串行化(ClientManage.SendLock);新增 SetRawDataHandler(Func<string, ReadOnlyMemory<byte>, CancellationToken, ValueTask>? handler)(原始载荷直送高频适配层)与 SendFrameDirectAsync(ReadOnlyMemory<byte> frame, string address, CancellationToken token = default)(把调用方组好的完整帧直接写入指定客户端;客户端不存在/已关闭返回 false,不做分块与重试)。

using Snet.Core.communication.net.tcp.service;
using static Snet.Core.communication.net.tcp.service.TcpServiceData;

var config = new Basics { IpAddress = "0.0.0.0", Port = 6688 };
var server = await TcpServiceOperate.InstanceAsync(config);

// 监听客户端事件(连接/断开/消息)
server.OnDataEvent += (sender, e) =>
{
    if (e.ResultData is ClientMessage msg)
    {
        switch (msg.Step)
        {
            case Steps.客户端连接: // Client Connected
                Console.WriteLine($"客户端连接:{msg.IpPort}"); break;
            case Steps.客户端断开: // Client Disconnected
                Console.WriteLine($"客户端断开:{msg.IpPort}"); break;
            case Steps.消息接收: // Message Received
                Console.WriteLine($"来自 {msg.IpPort}:{msg.Bytes?.Length} 字节"); break;
        }
    }
};

await server.OnAsync();

// 广播到所有已连接客户端
await server.SendAsync(Encoding.UTF8.GetBytes("大家好!"));

// 发送到指定客户端
await server.SendAsync(Encoding.UTF8.GetBytes("你好!"), "192.168.1.10:12345");

// 断开指定客户端
await server.RemoveAsync(new[] { "192.168.1.10:12345" });

await server.OffAsync();

3. 串口 -- SerialOperate

继承: CommunicationAbstract<SerialOperate, SerialData.Basics>

命名空间: Snet.Core.communication.serial

配置属性 类型 默认值 说明
PortName string "COM1" 串口号
BaudRate int 19200 波特率
ParityBit Parity Even 校验位(None/Odd/Even/Mark/Space)
DataBit int 8 数据位
StopBit StopBits One 停止位
WriteTimeout int 1000 写入超时(毫秒)
ReadTimeout int 1000 读取超时(毫秒)
ReceivedBytesThreshold int 1 接收数据阈值
SendWaitInterval int 5000 发送等待读取超时(毫秒)
MaxChunkSize int 261120 每块最大字节数
RetrySendCount int 5 每块重试次数
BufferSize int 1048576 接收缓冲区(1 MB)

静态方法: SerialOperate.GetPortArray() 返回可用串口列表 List<string>

特性: DataReceived 事件监控、SendWait 时 DetachMonitor/AttachMonitor 独占控制。

using Snet.Core.communication.serial;
using static Snet.Core.communication.serial.SerialData;

// 列出可用串口
var ports = SerialOperate.GetPortArray();
Console.WriteLine($"可用串口:{string.Join(", ", ports)}");

var config = new Basics
{
    PortName = "COM3",
    BaudRate = 9600,
    ParityBit = System.IO.Ports.Parity.None,
    DataBit = 8,
    StopBit = System.IO.Ports.StopBits.One
};

var serial = await SerialOperate.InstanceAsync(config);

serial.OnDataEvent += (sender, e) =>
{
    if (e.Status && e.ResultData is byte[] data)
        Console.WriteLine($"串口接收:{BitConverter.ToString(data)}");
};

await serial.OnAsync();
await serial.SendAsync(new byte[] { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01 });

// 发送并等待响应
var response = await serial.SendWaitAsync(
    new byte[] { 0x01, 0x03, 0x00, 0x00, 0x00, 0x01 },
    CancellationToken.None);

await serial.OffAsync();

4. WebSocket 客户端 -- WsClientOperate

继承: CommunicationAbstract<WsClientOperate, WsClientData.Basics>

命名空间: Snet.Core.communication.net.ws.client

配置属性 类型 默认值 说明
Host string "ws://127.0.0.1:6688/" WebSocket 服务器 URL
InterruptReconnection bool true 自动重连
ReconnectionInterval int 1000 重连间隔(毫秒)
Timeout int 1000 I/O 超时(毫秒)
SendWaitInterval int 5000 发送等待超时(毫秒)
MaxChunkSize int 261120 每块最大字节数
RetrySendCount int 5 每块重试次数
BufferSize int 1048576 接收缓冲区(1 MB)

特性: 基于 ClientWebSocket,指数退避重连,优雅关闭(Abort 回退)。2026-08 重构起:SendAsync/SendWaitAsync 经实例内部请求锁串行化;分块载荷以 WebSocket 分片(fragmentation)发送为一条逻辑消息(仅最后一片 endOfMessage = true;旧行为每块各自是完整消息);响应整体接收(分片由 ReceiveMessageAsync 重组)。MaxChunkSize ≤ 0 时发送直接失败。

using Snet.Core.communication.net.ws.client;
using static Snet.Core.communication.net.ws.client.WsClientData;

var config = new Basics { Host = "ws://192.168.1.100:6688/ws" };
var wsClient = await WsClientOperate.InstanceAsync(config);

wsClient.OnDataEvent += (sender, e) =>
{
    if (e.Status && e.ResultData is byte[] data)
        Console.WriteLine($"WebSocket 接收:{data.Length} 字节");
};

await wsClient.OnAsync();
await wsClient.SendAsync(Encoding.UTF8.GetBytes("你好 WebSocket!"));
await wsClient.OffAsync();

5. WebSocket 服务端 -- WsServiceOperate

继承: CommunicationServiceAbstract<WsServiceOperate, WsServiceData.Basics>

命名空间: Snet.Core.communication.net.ws.service

配置属性 类型 默认值 说明
Host string "ws://127.0.0.1:6688/" 监听地址(自动将 ws:// 转换为 http://)
MaxChunkSize int 261120 每块最大字节数
RetrySendCount int 5 每块重试次数
Timeout int 1000 I/O 超时(毫秒)
BufferSize int 1048576 接收缓冲区(1 MB)

事件: ClientMessage 包含 StepsIpPortBytes

特性: 基于 HttpListener 的 WebSocket 升级,ConcurrentDictionary 客户端管理,广播 + 定向发送,RemoveAsync。分块发送与 WS 客户端相同(一条逻辑消息 + 分片)。

using Snet.Core.communication.net.ws.service;
using static Snet.Core.communication.net.ws.service.WsServiceData;

var config = new Basics { Host = "ws://0.0.0.0:8080/" };
var wsServer = await WsServiceOperate.InstanceAsync(config);

wsServer.OnDataEvent += (sender, e) =>
{
    if (e.ResultData is ClientMessage msg)
    {
        Console.WriteLine($"[{msg.Step}] {msg.IpPort}");
        if (msg.Bytes != null)
            Console.WriteLine($"  数据:{msg.Bytes.Length} 字节");
    }
};

await wsServer.OnAsync();
await wsServer.SendAsync(Encoding.UTF8.GetBytes("欢迎!"));
await wsServer.OffAsync();

6. UDP 单播客户端 -- UdpClientOperate

继承: CommunicationAbstract<UdpClientOperate, UdpClientData.Basics>

命名空间: Snet.Core.communication.net.udp.unicast.client

配置属性 类型 默认值 说明
IpAddress string "127.0.0.1" 远程 IP
Port int 6688 远程端口
LocalPort int 0 本地绑定端口(0 = 自动分配)
InterruptReconnection bool true 自动重连
ReconnectionInterval int 1000 重连间隔(毫秒)
Timeout int 1000 I/O 超时(毫秒)
SendWaitInterval int 5000 发送等待超时(毫秒)
MaxChunkSize int 261120 每块最大字节数
RetrySendCount int 5 每块重试次数

UDP 发送语义(2026-08 重构起): 载荷作为一个数据报发送,无自动分割——有效上限为 min(MaxChunkSize, 60 KiB);更大的载荷被拒绝(发送失败),每次尝试最多重试 RetrySendCount 次。

using Snet.Core.communication.net.udp.unicast.client;
using static Snet.Core.communication.net.udp.unicast.client.UdpClientData;

var config = new Basics
{
    IpAddress = "192.168.1.100",
    Port = 6688,
    LocalPort = 0  // 系统自动分配
};

var udpClient = await UdpClientOperate.InstanceAsync(config);

udpClient.OnDataEvent += (sender, e) =>
{
    if (e.Status && e.ResultData is byte[] data)
        Console.WriteLine($"UDP 接收:{data.Length} 字节");
};

await udpClient.OnAsync();
await udpClient.SendAsync(Encoding.UTF8.GetBytes("UDP 数据报!"));
await udpClient.OffAsync();

7. UDP 单播服务端 -- UdpServiceOperate

继承: CommunicationServiceAbstract<UdpServiceOperate, UdpServiceData.Basics>

命名空间: Snet.Core.communication.net.udp.unicast.service

配置属性 类型 默认值 说明
IpAddress string "127.0.0.1" 绑定地址
Port int 6688 监听端口
MaxChunkSize int 261120 每块最大字节数
RetrySendCount int 5 每块重试次数
Timeout int 1000 I/O 超时(毫秒)
ClientTimeout int 60000 客户端端点空闲超时(毫秒)

特性: 单一接收循环自动发现客户端端点,ConcurrentDictionary 管理已知客户端,广播 + 定向发送,RemoveAsync。UDP 发送上限(每数据报 min(MaxChunkSize, 60 KiB),无分割)同样适用。

using Snet.Core.communication.net.udp.unicast.service;
using static Snet.Core.communication.net.udp.unicast.service.UdpServiceData;

var config = new Basics { IpAddress = "0.0.0.0", Port = 6688 };
var udpServer = await UdpServiceOperate.InstanceAsync(config);

udpServer.OnDataEvent += (sender, e) =>
{
    if (e.ResultData is ClientMessage msg)
        Console.WriteLine($"[{msg.Step}] {msg.IpPort}:{msg.Bytes?.Length} 字节");
};

await udpServer.OnAsync();

// 广播到所有已知客户端
await udpServer.SendAsync(Encoding.UTF8.GetBytes("你好 UDP 客户端们!"));

// 发送到指定客户端
await udpServer.SendAsync(
    Encoding.UTF8.GetBytes("你好!"),
    "192.168.1.10:5000");

await udpServer.OffAsync();

8. UDP 组播 -- UdpMulticastOperate

继承: CommunicationAbstract<UdpMulticastOperate, UdpMulticastData.Basics>

命名空间: Snet.Core.communication.net.udp.multicast

配置属性 类型 默认值 说明
Port int 6688 本地绑定端口
MulticastAddress string "239.0.0.1" 组播组地址
MulticastPort int 8866 目标发送端口(0 = 使用 Port)
TimeToLive short 1 生存时间(0=仅本机,1=本地子网...)
Timeout int 1000 I/O 超时(毫秒)
SendWaitInterval int 5000 发送等待超时(毫秒)
MaxChunkSize int 261120 每块最大字节数
RetrySendCount int 5 每块重试次数

注意: EffectiveMulticastPort 取值为 MulticastPort > 0 ? MulticastPort : Port

特性: JoinMulticastGroup / DropMulticastGroupReuseAddressMulticastTimeToLive,全接口绑定(IPAddress.Any)。UDP 发送上限:每数据报 min(MaxChunkSize, 60 KiB),无分割。

using Snet.Core.communication.net.udp.multicast;
using static Snet.Core.communication.net.udp.multicast.UdpMulticastData;

var config = new Basics
{
    Port = 6688,
    MulticastAddress = "239.0.0.1",
    MulticastPort = 8866,
    TimeToLive = 1  // 仅本地子网
};

var multicast = await UdpMulticastOperate.InstanceAsync(config);

multicast.OnDataEvent += (sender, e) =>
{
    if (e.Status && e.ResultData is byte[] data)
        Console.WriteLine($"组播接收:{data.Length} 字节");
};

await multicast.OnAsync();
await multicast.SendAsync(Encoding.UTF8.GetBytes("你好组播组!"));
await multicast.OffAsync();

9. UDP 广播 -- UdpBroadcastOperate

继承: CommunicationAbstract<UdpBroadcastOperate, UdpBroadcastData.Basics>

命名空间: Snet.Core.communication.net.udp.broadcast

配置属性 类型 默认值 说明
Port int 6688 本地绑定端口
BroadcastAddress string "255.255.255.255" 广播地址
BroadcastPort int 8866 目标发送端口(0 = 使用 Port)
Timeout int 1000 I/O 超时(毫秒)
SendWaitInterval int 5000 发送等待超时(毫秒)
MaxChunkSize int 261120 每块最大字节数
RetrySendCount int 5 每块重试次数

注意: EffectiveBroadcastPort 取值为 BroadcastPort > 0 ? BroadcastPort : Port

特性: EnableBroadcast = trueReuseAddressIPAddress.Any 绑定。UDP 发送上限:每数据报 min(MaxChunkSize, 60 KiB),无分割。

using Snet.Core.communication.net.udp.broadcast;
using static Snet.Core.communication.net.udp.broadcast.UdpBroadcastData;

var config = new Basics
{
    Port = 6688,
    BroadcastAddress = "255.255.255.255",
    BroadcastPort = 8866
};

var broadcast = await UdpBroadcastOperate.InstanceAsync(config);

broadcast.OnDataEvent += (sender, e) =>
{
    if (e.Status && e.ResultData is byte[] data)
        Console.WriteLine($"广播接收:{data.Length} 字节");
};

await broadcast.OnAsync();
await broadcast.SendAsync(Encoding.UTF8.GetBytes("你好广播!"));
await broadcast.OffAsync();

10. HTTP 客户端 -- HttpClientOperate

继承: CoreUnify<HttpClientOperate, HttpClientData.Basics>

命名空间: Snet.Core.communication.net.http.client

配置(Basics):

属性 类型 默认值 说明
MaxConnectCount int 255 每服务器最大连接数

RequestData

属性 类型 默认值 说明
Url string "http://127.0.0.1:6688/api/snet" 请求 URL
Headers ConcurrentDictionary<string,string> {}(不区分大小写) 自定义请求头
Method HttpMethod GET HTTP 方法
BodyType BType 枚举 Raw FormData / Raw / None
BodyContent object null Raw 时 string,FormData 时 IReadOnlyDictionary<string,string>
Encoding Encoding UTF8 内容编码
ContentType string "application/json" Content-Type 头
TimeOut TimeSpan 60s 请求超时
Proxy IWebProxy? null 代理设置
CookieContainer CookieContainer new() Cookie 存储

ResponseData StatusCode(int)、ResHeadersDatasConcurrentDictionary<string,string>?)、ResCookieDataResData(string)、ReqData

特别说明: 直接继承 CoreUnify(非 CommunicationAbstract)。使用 SocketsHttpHandler 连接池和 Cookie 管理。支持自动内容头路由(Content-Type 等路由到内容头而非请求头)。2026-08 重构起 RequestAsync 先校验 URL:requestDatanullArgumentNullException;非绝对地址或非 HTTP(S) 地址抛 ArgumentException(旧行为是这类无效 URL 以失败 OperateResult 返回)。

using Snet.Core.communication.net.http.client;
using static Snet.Core.communication.net.http.client.HttpClientData;

var httpClient = await HttpClientOperate.InstanceAsync(new Basics());

// GET 请求
var req = new RequestData
{
    Url = "https://api.example.com/data",
    Method = HttpMethod.Get
};
var response = await httpClient.RequestAsync(req);
if (response.Status && response.ResultData is ResponseData res)
    Console.WriteLine($"状态码={res.StatusCode},响应体={res.ResData}");

// POST JSON
var postReq = new RequestData
{
    Url = "https://api.example.com/data",
    Method = HttpMethod.Post,
    BodyType = BType.Raw,
    BodyContent = "{\"name\":\"value\"}",
    ContentType = "application/json"
};
await httpClient.RequestAsync(postReq);

// POST 表单
var formReq = new RequestData
{
    Url = "https://api.example.com/upload",
    Method = HttpMethod.Post,
    BodyType = BType.FormData,
    BodyContent = new Dictionary<string, string> { ["field1"] = "value1" }
};
await httpClient.RequestAsync(formReq);

// 带 Cookie 和代理
var proxyReq = new RequestData
{
    Url = "https://api.example.com/secure",
    Method = HttpMethod.Get,
    Proxy = new System.Net.WebProxy("http://proxy:8080"),
    CookieContainer = new System.Net.CookieContainer()
};
await httpClient.RequestAsync(proxyReq);

11. HTTP 服务端 -- HttpServiceOperate

继承: CoreUnify<HttpServiceOperate, HttpServiceData.Basics>,实现 IOnIOffIStatus

命名空间: Snet.Core.communication.net.http.service

配置(Basics 继承 WAModel):

属性 类型 默认值 说明
ContentType string "application/json" 请求/响应 Content-Type
AbsolutePaths List<AbsolutePathsModel> [new("/api/snet", HttpMethod.Get)] 有效 API 路径(每项自带 HttpMethod
AllowedOrigins List<string> [] 跨域来源精确白名单;空 = 不信任任何跨域来源
MaxRequestBodyBytes int 1048576(1 MiB) 请求体最大字节数;超限返回 413
CrossDomain bool 继承(false 跨域处理开关
IpAddress string 继承("127.0.0.1" 监听地址
Port int 继承(6688 监听端口

特别说明: 使用 HttpListenerHandlerIncomingConnectionsAsync 在分发前验证方法、路径和内容类型。CORS 为白名单制(2026-08 重构起):CrossDomain = true 时仅当请求 Origin 精确命中 AllowedOrigins 才写入 Access-Control-Allow-Origin 与凭据头;OPTIONS 预检请求命中白名单返回 204,未命中返回 403。请求体超过 MaxRequestBodyBytes 时返回 413WriteAsync<T> 是静态泛型方法用于写入 JSON 响应。

WaitHandler 数据类: Request(HttpListenerRequest)、Response(HttpListenerResponse)、BodyData(string?)。

using Snet.Core.communication.net.http.service;
using static Snet.Core.communication.net.http.service.HttpServiceData;

var config = new Basics
{
    IpAddress = "0.0.0.0",
    Port = 8080,
    ContentType = "application/json",
    CrossDomain = true,
    AllowedOrigins = new List<string> { "http://localhost:3000" },
    AbsolutePaths = new List<AbsolutePathsModel>
    {
        new("/api/snet", HttpMethod.Post),
        new("/api/health", HttpMethod.Get)
    }
};

var httpServer = await HttpServiceOperate.InstanceAsync(config);

// 处理传入 API 请求
httpServer.OnDataEvent += async (sender, e) =>
{
    if (e.ResultData is WaitHandler wh)
    {
        Console.WriteLine($"请求路径:{wh.Request.Url!.AbsolutePath}");
        Console.WriteLine($"请求体:{wh.BodyData}");

        // 写入 JSON 响应
        await HttpServiceOperate.WriteAsync(
            wh.Response,
            new { status = "ok", message = "来自 Snet 的问候!" });
    }
};

await httpServer.OnAsync();
// 服务器监听 http://0.0.0.0:8080/api/snet

await httpServer.OffAsync();

12. 通道(有界) -- ChannelOperate<T>

继承: CoreUnify<ChannelOperate<T>, ChannelData>

命名空间: Snet.Core.channel

(约束:T : notnull

配置属性 类型 默认值 说明
Capacity int 65535 通道最大容量
SingleReader bool false 单读取器优化
SingleWriter bool false 单写入器优化
IsSync bool true true = 手动读取;false = 自动事件分发

方法:

方法 说明
WriteAsync(T, token) 入队(满时等待)
TryWrite(T) 非阻塞入队
ReadAsync(token) 出队(空时等待,仅同步模式)
ReadWaitAsync(timeOut, token) 出队带超时(仅同步模式)
TryRead() / TryRead(out T) 非阻塞出队
ResetChannel() / ResetChannelAsync() 重置复用(释放后不可用——抛出 ObjectDisposedException,应新建实例)
Reader / Writer 直接访问 ChannelReader<T> / ChannelWriter<T>
IsDisposed 释放后为 true(不可恢复)
Count 通道中的近似数据量

模式:

  • 同步(IsSync = true): 调用方通过 ReadAsync / TryRead 手动读取。
  • 异步(IsSync = false): 后台循环通过 OnDataEvent 回调自动分发数据。

线程安全: Interlocked.CompareExchange 无锁懒初始化、SemaphoreSlim 重置锁、原子 _disposed 标志(Interlocked/Volatile)。2026-08 重构起已释放实例不能再重置复用——ResetChannelAsync 调用 ThrowIfDisposed() 抛异常;请新建实例。

using Snet.Core.channel;

// 同步模式:手动读写
var chConfig = new ChannelData { Capacity = 1024, IsSync = true };
var channel = await ChannelOperate<string>.InstanceAsync(chConfig);

await channel.WriteAsync("item-1", CancellationToken.None);
await channel.WriteAsync("item-2", CancellationToken.None);

var result = await channel.ReadAsync(CancellationToken.None);
Console.WriteLine($"读取:{result.ResultData}");  // "item-1"

// TryRead(非阻塞)
if (channel.TryRead(out string value))
    Console.WriteLine($"TryRead:{value}");  // "item-2"

// 异步模式:自动事件分发
var asyncConfig = new ChannelData { Capacity = 1024, IsSync = false };
var asyncChannel = await ChannelOperate<int>.InstanceAsync(asyncConfig);

asyncChannel.OnDataEvent += (sender, e) =>
{
    if (e.Status && e.ResultData is int number)
        Console.WriteLine($"自动接收:{number}");
};

await asyncChannel.WriteAsync(42, CancellationToken.None);
await asyncChannel.WriteAsync(99, CancellationToken.None);

通用使用模式(所有客户端传输)

所有客户端传输(CommunicationAbstract 子类)遵循 6 步生命周期:

1. 创建配置    new Basics { IpAddress = "...", Port = 6688 }
2. 获取单例    await OperateType.InstanceAsync(config)
3. 连接        await client.OnAsync()
4. 发送        await client.SendAsync(data)
5. 发送+等待   await client.SendWaitAsync(data, token)
6. 断开        await client.OffAsync()

每个操作返回 OperateResult,包含 .Status(bool)、.Message(string)、.ResultData(object?)和 .RunTime(毫秒)。

数据流

应用程序代码
     |
     +-- OnDataEvent(订阅)  <-- 来自传输层的接收数据
     |
     +-- SendAsync(data) -----------> 传输层 ------> 网络
     |
     +-- SendWaitAsync(data, token) -> 传输层 <=====> 网络
                                      (停止监控,发送,读取,重启监控)

对于服务端传输,接收的数据以类型化的 ClientMessage 对象形式到达,包含 StepIpPortBytes

命名空间参考

传输 命名空间
TCP 客户端 Snet.Core.communication.net.tcp.client
TCP 服务端 Snet.Core.communication.net.tcp.service
串口 Snet.Core.communication.serial
WebSocket 客户端 Snet.Core.communication.net.ws.client
WebSocket 服务端 Snet.Core.communication.net.ws.service
UDP 单播客户端 Snet.Core.communication.net.udp.unicast.client
UDP 单播服务端 Snet.Core.communication.net.udp.unicast.service
UDP 组播 Snet.Core.communication.net.udp.multicast
UDP 广播 Snet.Core.communication.net.udp.broadcast
HTTP 客户端 Snet.Core.communication.net.http.client
HTTP 服务端 Snet.Core.communication.net.http.service
通道 Snet.Core.channel