Netty - Snet Docs

Netty TCP 中间件

包名: Snet.Netty | 类: NettyClientOperate | 基类: MqAbstract<NettyClientOperate, NettyClientData.Basics>

基于 DotNetty 库(Netty 的 .NET 移植版本)提供高性能 TCP 消息传递。支持自定义协议帧解析、编码器/解码器管道和长生命周期持久 TCP 连接。

概述

NettyClientOperate 封装了 DotNetty TCP 通道,并在原始 TCP 之上提供基于消息的发布/订阅语义。它继承自 MqAbstract<NettyClientOperate, NettyClientData.Basics> 并实现了 IMq

当您需要通过自定义协议处理进行原始 TCP 消息传递时,这是正确的选择 -- 例如,与嵌入式设备、专有 PLC 接口或使用自定义有线协议的遗留系统通信。

安装

dotnet add package Snet.Netty

快速开始

using Snet.Netty.client;

var client = await NettyClientOperate.InstanceAsync(new NettyClientData.Basics
{
    IpAddress = "127.0.0.1",
    Port = 6688
});

await client.OnAsync();

// 绑定事件再消费
client.OnDataEventAsync += async (sender, e) =>
{
    if (e.Status)
        Console.WriteLine($"接收到数据: {e.ResultData}");
    else
        Console.WriteLine($"消费失败: {e.Message}");
};

await client.ConsumeAsync("command");

// 生产消息(可选)
await client.ProduceAsync("command", "STATUS", System.Text.Encoding.UTF8);

// 后续:取消消费
// await client.UnConsumeAsync("command");
// await client.DisposeAsync();

生产与消费

发布与订阅是 IMq 的一等操作——先绑定数据事件,再消费;发布可用字符串或原始字节:

// 1) 先绑定事件再消费——收到的消息在此到达
client.OnDataEventAsync += async (sender, e) =>
{
    if (e.Status)
        Console.WriteLine($"收到: {e.ResultData}");
    else
        Console.WriteLine($"消费失败: {e.Message}");
};

// 2) 消费:订阅主题
await client.ConsumeAsync("command");

// 3) 生产:发布字符串消息(UTF-8)
await client.ProduceAsync("command", "STATUS", System.Text.Encoding.UTF8);

// 4) 生产:发布原始字节
var bytes = System.Text.Encoding.UTF8.GetBytes("payload");
await client.ProduceAsync("command", bytes);

// 后续:停止消费
// await client.UnConsumeAsync("command");

ProduceAsync(topic, string, Encoding?)ProduceAsync(topic, byte[]) 均可发布;ConsumeAsync/UnConsumeAsync 管理主题订阅。事件见:事件

配置

参数 类型 默认值 描述
IpAddress string "127.0.0.1" 目标服务器 IP 地址
Port int 6688 目标服务器 TCP 端口
SslFilePath string? SSL 证书文件路径
SslFilePassword string? SSL 证书文件密码
TLS 校验

配置 SslFilePath 后客户端会校验服务器证书链与主机名——自签名或主机名不匹配的证书将被拒绝连接。 | TaskNumber | int | 5 | 并发任务数量 | | ResponseType | enum | Content | 响应类型 |

协议管道

DotNetty 使用通道处理器管道进行协议处理。默认管道为:

  1. LengthFieldPrepender(8) -- 为每个出站帧前置 8 字节长度字段
  2. LengthFieldBasedFrameDecoder -- 按 8 字节长度字段将入站字节流分割为消息帧
  3. NettyClientHandler -- 将消息分发到应用层

管道中没有字符串编解码器(消息以原始字节交换;长度字段固定为 8 字节),且管道由客户端内部构建——没有可扩展管道的公共 API。

支持的操作

操作 方法 描述
连接 OnAsync() 建立到服务器的 TCP 连接
断开 OffAsync() 关闭 TCP 连接
发送 ProduceAsync(topic, string, Encoding?) 通过 TCP 发送字符串消息
发送 ProduceAsync(topic, byte[]) 通过 TCP 发送原始字节
接收 ConsumeAsync(topic) 开始监听主题/通道上的消息
停止接收 UnConsumeAsync(topic) 停止监听主题/通道上的消息

事件

事件 签名 描述
OnDataEvent EventHandler<EventDataResult> 从 TCP 连接收到数据时触发
OnDataEventAsync EventHandlerAsync<EventDataResult> OnDataEvent 的异步变体
OnInfoEvent EventHandler<EventInfoResult> 收到连接状态和信息消息时触发
OnInfoEventAsync EventHandlerAsync<EventInfoResult> OnInfoEvent 的异步变体
OnLanguageEvent EventHandler<EventLanguageResult> 语言变更时触发
OnLanguageEventAsync EventHandlerAsync<EventLanguageResult> OnLanguageEvent 的异步变体

连接异常处理

连接异常时,库会抛出信息事件(含远端 IP:Port 与异常消息),随后关闭通道并置空内部 Channel 引用——不调用 Off(true)、不会自动重连。断线后的清理与重连需由调用方通过 On/Off 生命周期管理;通道关闭期间 GetStatusAsync() 返回「未连接」。示例:

// 事件驱动的重连(由调用方管理)
client.OnInfoEventAsync += async (sender, result) =>
{
    if (!result.Status)
    {
        await Task.Delay(2000);
        await client.OnAsync(); // 尝试重连
    }
};

另请参阅