Snet 框架文档
最后更新: 2026-07-21 | 目标框架: .NET 10 | 语言: C# 14
概述
Snet 是面向 .NET 10 的统一工业通信框架。它提供基于插件架构的统一接口,用于连接 PLC、机器人、仪器仪表、数据库和消息队列。该框架通过公共 API 抽象了各厂商硬件协议,使工程师能够在不重写应用逻辑的情况下切换不同品牌的设备。
核心特性
- 30+ 种工业协议驱动,覆盖 PLC、仪器仪表和机器人
- 插件架构,支持基于
AssemblyLoadContext 的热重载
- 多传输层网络支持:TCP、UDP、串口、WebSocket、HTTP
- 统一地址系统,支持 Protobuf 序列化
- 框架内置中英文双语支持
- 基于
ConcurrentDictionary 池的线程安全单例管理
- 同步/异步事件对的驱动数据传播
- 基于 Serilog 的结构化日志(6 个级别)
- 共享内存缓存和进程内存缓存
- 虚拟地址模拟,支持离线测试
架构
+------------------------------------------------------------------+
| 您的应用程序 |
+------------------------------------------------------------------+
|
v
+------------------------------------------------------------------+
| SNET.DRIVER (协议层) |
| Modbus | Siemens | Allen-Bradley | Mitsubishi | Omron | Beckhoff|
| Keyence | Delta | Fuji | GE | Inovance | Panasonic | XinJE ... |
| DLT645/698 | CJT188 | IEC104 | RKC | Yudian | ... |
+------------------------------------------------------------------+
|
v
+------------------------------------------------------------------+
| SNET.CORE (基础层) |
| CoreUnify (单例池) | DaqAbstract | MqAbstract |
| CommunicationAbstract | CommunicationServiceAbstract |
| TCP/UDP/Serial/WS/HTTP 传输操作器 |
| 插件系统 | 缓存 | 订阅 | 虚拟地址 |
+------------------------------------------------------------------+
|
v
+------------------------------------------------------------------+
| SNET.MODEL (契约层) |
| 数据模型 | 枚举 | 接口 | 特性 | 事件 |
+------------------------------------------------------------------+
|
v
+------------------------------------------------------------------+
| SNET.UTILITY (工具层) |
| 扩展方法 | 序列化 | 对象比较 | 处理器 |
+------------------------------------------------------------------+
各层职责
| 层次 |
NuGet 包 |
职责 |
| Snet.Model |
契约 |
数据模型、枚举(8种)、接口(26个)、特性(7个)、事件系统 |
| Snet.Core |
基础 |
抽象基类、12种传输操作器、插件系统、缓存 |
| Snet.Utility |
工具 |
150+ 扩展方法、序列化、对象比较框架 |
快速入门
安装
# 安装核心包
dotnet add package Snet.Core
dotnet add package Snet.Model
dotnet add package Snet.Utility
# 按需安装协议驱动
dotnet add package Snet.Modbus
dotnet add package Snet.Siemens
基本用法:读取 Modbus TCP 设备
using Snet.Core;
using Snet.Modbus;
using Snet.Model.data;
// 创建 Modbus TCP 客户端
var modbus = new ModbusOperate()
{
IpAddress = "192.168.1.100",
Port = 502,
Station = 1,
ConnectTimeOut = 3000
};
// 打开连接
var result = await modbus.OpenAsync();
if (!result.IsSuccess)
{
Console.WriteLine($"连接失败: {result.Message}");
return;
}
// 读取保持寄存器,起始地址 40001
var readResult = await modbus.ReadAsync("40001", 10);
if (readResult.IsSuccess)
{
foreach (var value in readResult.Values)
Console.WriteLine($"值: {value}");
}
// 关闭连接
await modbus.CloseAsync();
使用单例池(推荐方式)
using Snet.Core;
// 在池中注册设备(最多 255 个实例)
var key = "MyModbusDevice";
CoreUnify.Instance[key] = new ModbusOperate()
{
IpAddress = "192.168.1.100",
Port = 502,
Station = 1
};
// 在其他任意位置获取并使用
if (CoreUnify.Instance.GetValue(key) is ModbusOperate device)
{
await device.OpenAsync();
var result = await device.ReadAsync("40001", 10);
await device.CloseAsync();
}
核心概念
1. 地址系统
统一地址系统将各厂商硬件地址规范化为通用管道:
Address --> AddressDetails --> AddressValue --> AddressValueSimplify
(原始字符串) (解析/路由) (类型化数据) (Protobuf 序列化)
- Address -- 原始字符串表示(如
"40001", "DB1.DBX0.0", "D100")
- AddressDetails -- 包含路由元数据的解析结构
- AddressValue -- 带时间戳和质量指示的类型化值
- AddressValueSimplify -- 用于网络传输的紧凑 Protobuf 表示
2. 结果模型
每个操作返回一个 OperateResult<T> 封装成功/失败状态:
public class OperateResult<T>
{
public bool IsSuccess { get; set; }
public string Message { get; set; }
public T Content { get; set; }
}
使用模式:
var result = await device.ReadAsync("40001", 10);
if (!result.IsSuccess)
{
_logger.Error($"读取失败: {result.Message}");
return;
}
ProcessValues(result.Content);
3. 事件系统
Snet 使用自定义委托架构提供配对的同步和异步事件:
| 组件 |
用途 |
EventArgsAsync |
带回调支持的异步事件参数 |
EventHandlerAsync |
异步事件处理委托类型 |
EventingWrapperAsync |
值类型包装器,高效事件链 |
事件从设备驱动向上通过抽象层传播,实现响应式监控:
modbus.OnDataReceived += async (sender, args) =>
{
Console.WriteLine($"从设备接收到 {args.Data.Length} 字节");
await ProcessDataAsync(args.Data);
};
4. 插件系统
插件通过 AssemblyLoadContext 加载,支持热重载。内核维护一个限制为 255 个实例的 ConcurrentDictionary 池。
// 加载插件程序集
var plugin = PluginOperate.Load("path/to/plugin.dll");
// 使用上下文隔离实例化
var instance = plugin.CreateInstance<IDaq>("Snet.CustomDriver");
CoreUnify.Instance["custom"] = instance;
5. 数据类型
DataType 枚举定义了 40 种类型,包括标量和数组,支持别名:
| 类别 |
类型 |
| 标量 |
Bool(布尔)、Byte(字节)、Short/Int16(16位有符号)、UShort/UInt16(16位无符号)、Int/Int32(32位有符号)、UInt/UInt32(32位无符号)、Long/Int64(64位有符号)、ULong/UInt64(64位无符号)、Float/Single(单精度浮点)、Double(双精度浮点)、String(字符串)、Char(字符)、DateTime(日期时间)、Date(日期)、Time(时间) |
| 数组 |
BoolArray、ByteArray、ShortArray/Int16Array、UShortArray/UInt16Array、IntArray/Int32Array、UIntArray/UInt32Array、LongArray/Int64Array、ULongArray/UInt64Array、FloatArray/SingleArray、DoubleArray |
6. CoreUnify 单例池
CoreUnify 是中央单例管理器,提供:
- 最多 255 个实例,存储在
ConcurrentDictionary<string, object> 池中
- 已注册设备间的事件传播
- 通过 Serilog 的日志集成(Trace、Debug、Info、Warn、Error、Fatal)
- 内置中英文资源文件的语言管理
协议驱动
Snet.Driver 按厂商提供协议实现:
Modbus 系列 (Snet.Modbus)
| 协议 |
类 |
传输方式 |
| Modbus TCP |
标准 Modbus TCP |
以太网 |
| Modbus RTU |
串口 RTU 帧格式 |
RS-232/485 |
| Modbus ASCII |
串口 ASCII 帧格式 |
RS-232/485 |
| Modbus UDP |
UDP 传输 |
以太网 |
西门子系列 (Snet.Siemens)
| 协议 |
类 |
目标设备 |
| S7-200/300/400/1200/1500 |
SiemensS7Net |
S7 系列 PLC 以太网 |
| Fetch/Write |
SiemensFetchWriteNet |
旧版 S5/S7 |
| PPI |
SiemensPPI / SiemensPPIOverTcp |
S7-200 系列 |
| S7 Plus |
SiemensS7Plus |
S7-1200/1500 优化协议 |
Allen-Bradley 系列 (Snet.AllenBradley)
| 协议 |
类 |
目标设备 |
| EtherNet/IP (CIP) |
AllenBradleyNet |
ControlLogix / CompactLogix |
| Connected CIP |
AllenBradleyConnectedCipNet |
基于会话的 CIP |
| Micro800 |
AllenBradleyMicroCip |
Micro800 系列 |
| PCCC |
AllenBradleyPcccNet |
PLC-5 / SLC-500 |
| SLC |
AllenBradleySLCNet |
SLC 系列 |
| DF1 |
AllenBradleyDF1Serial |
旧版串口协议 |
三菱/Melsec 系列 (Snet.Mitsubishi)
| 协议 |
类 |
格式 |
| MC 二进制 |
MelsecMcNet / MelsecMcUdp |
二进制帧格式 |
| MC ASCII |
MelsecMcAsciiNet / MelsecMcAsciiUdp |
ASCII 帧格式 |
| MC R |
MelsecMcRNet |
R 系列 |
| A-1E |
MelsecA1ENet |
旧版 AnS 系列 |
| A-3C |
MelsecA3CNet / MelsecA3CNetOverTcp |
旧版串口 |
| FX 串口 |
MelsecFxSerial / MelsecFxSerialOverTcp |
FX 系列 |
| FX Links |
MelsecFxLinks / MelsecFxLinksOverTcp |
FX 系列链接 |
| CIP |
MelsecCipNet |
EtherNet/IP |
欧姆龙系列 (Snet.Omron)
| 协议 |
类 |
传输方式 |
| FINS TCP |
OmronFinsNet |
以太网 |
| FINS UDP |
OmronFinsUdp |
UDP |
| HostLink |
OmronHostLink / OmronHostLinkOverTcp |
串口/以太网 |
| HostLink C-Mode |
OmronHostLinkCMode / OmronHostLinkCModeOverTcp |
串口/以太网 |
| CIP |
OmronCipNet / OmronConnectedCipNet |
EtherNet/IP |
倍福 (Snet.Beckhoff)
| 协议 |
类 |
传输方式 |
| ADS |
BeckhoffAdsNet |
TCP (AMS/TCP) |
其他 PLC 厂商
| 厂商 |
NuGet 包 |
协议 |
| 基恩士 Keyence |
Snet.Keyence |
KV 系列、Nano 串口、DL-EN1、SR-2000、MC |
| 台达 Delta |
Snet.Delta |
DVP/AS 系列 |
| 富士 Fuji |
Snet.Fuji |
SPH/SPB 系列 |
| 通用电气 GE |
Snet.GE |
SRTP |
| 汇川 Inovance |
Snet.Inovance |
Modbus 协议 |
| 松下 Panasonic |
Snet.Panasonic |
MEWTOCOL |
| 信捷 XinJE |
Snet.XinJE |
XD/XL 系列 |
| 横河 Yokogawa |
Snet.Yokogawa |
FA-M3 系列 |
| 安川 Yaskawa |
Snet.Yaskawa |
MP/Sigma 系列 |
| Cimon |
Snet.Cimon |
CIMON PLC |
| LSis |
Snet.LSis |
XGT 系列 |
| Fatek |
Snet.Fatek |
FBs 系列 |
| Vigor |
Snet.Vigor |
VB/VH 系列 |
| 维控 WeCon |
Snet.WeCon |
LX 系列 |
| Kossi |
Snet.Kossi |
Kossi PLC |
| MegMeet |
Snet.MegMeet |
MC 系列 |
| 发那科 Fanuc |
Snet.Fanuc |
Focas 协议 |
| 图尔克 Turck |
Snet.Turck |
BL 系列 |
| 东方马达 Oriental Motor |
Snet.OrientalMotor |
步进/伺服 |
| 丰田 Toyota |
Snet.Toyota |
Toyota PLC |
| Yamatake |
Snet.Yamatake |
Yamatake 控制器 |
| TEP |
Snet.TEP |
自定义协议 (Socket TCP) |
| OPC |
Snet.Opc |
OPC 连接 |
仪器仪表驱动 (Snet.Driver/Instrument)
| 协议 |
类 |
应用场景 |
| DLT645-1997 |
DLT645With1997 / OverTcp |
电表(中国标准,1997版) |
| DLT645-2007 |
DLT645 / OverTcp |
电表(中国标准,2007版) |
| DLT698 |
DLT698 / OverTcp / TcpNet |
智能电表(新一代) |
| CJT188 |
CJT188 / OverTcp |
水表/燃气表/热表 |
| IEC 60870-5-104 |
IEC104 / Server |
电力远动 |
| RKC |
RKC 温控器 |
温度仪表 |
| 宇电 Yudian |
宇电 AI 系列 |
温度控制器 |
中间件
消息队列集成
| NuGet 包 |
协议 |
功能特性 |
| Snet.Mqtt |
MQTT 3.1.1/5.0 |
客户端 + 服务端,QoS 0/1/2,保留消息 |
| Snet.Kafka |
Apache Kafka |
生产者/消费者,Topic 管理 |
| Snet.RabbitMQ |
AMQP 0-9-1 |
Exchange/Queue/Binding,RPC 模式 |
| Snet.NetMQ |
ZeroMQ |
PUB/SUB、REQ/REP、PUSH/PULL 模式 |
| Snet.Netty |
自定义 TCP 协议 |
客户端 + 服务端,高性能网络通信 |
数据库 (Snet.DB)
用于持久化工业数据的数据库集成。
工具库 (Snet.Utility)
扩展方法
150+ 扩展方法覆盖常见的工业数据操作、字节处理、网络操作和字符串处理。
对象比较框架
完整的深度比较引擎,支持:
- 可配置深度的递归属性比较
- 单属性自定义验证逻辑
- 差异报告(文本和 HTML 格式)
- 类型定制比较器
- 忽略模式与排除规则
var config = new ComparisonConfig { MaxDifferences = 100 };
var result = expected.CompareTo(actual, config);
if (!result.AreEqual)
{
foreach (var diff in result.Differences)
Console.WriteLine($"{diff.PropertyName}: {diff.Object1Value} != {diff.Object2Value}");
}
处理器
| 处理器 |
用途 |
ByteHandler |
字节数组操作、字节序转换 |
FileHandler |
文件 I/O 操作 |
NetHandler |
网络工具(ping、DNS、连通性) |
TimeHandler |
时间/日期转换工具 |
FtpHandler |
FTP 上传/下载操作 |
序列化
| 格式 |
库 |
| JSON |
System.Text.Json / Newtonsoft.Json |
| XML |
System.Xml |
| Protobuf |
Google.Protobuf |
传输层 (Snet.Core)
框架提供 12 种传输操作器,覆盖所有常见工业通信模式:
| 操作器 |
角色 |
用途 |
TcpClientOperate |
客户端 |
标准 TCP 通信 |
TcpServiceOperate |
服务端 |
TCP 监听器,多客户端支持 |
SerialOperate |
客户端 |
RS-232/485 串口通信 |
WsClientOperate |
客户端 |
WebSocket 客户端 |
WsServiceOperate |
服务端 |
WebSocket 服务端 |
UdpClientOperate |
客户端 |
单播 UDP |
UdpServiceOperate |
服务端 |
UDP 监听器 |
UdpMulticastOperate |
订阅者 |
组播组成员 |
UdpBroadcastOperate |
客户端 |
广播 UDP |
HttpServiceOperate |
服务端 |
HTTP 服务器 |
HttpClientOperate |
客户端 |
HTTP 客户端 |
ChannelOperate |
虚拟 |
进程间数据通道 |
接口契约 (Snet.Model)
26 个接口定义框架的契约体系:
| 接口 |
类别 |
描述 |
IOn / IOff |
生命周期 |
打开/关闭连接 |
IRead |
读取 |
从设备读取数据 |
IWrite |
写入 |
向设备写入数据 |
ISubscribe |
订阅 |
订阅数据变更 |
IEvent |
事件 |
事件注册与分发 |
IDaq |
数据采集 |
数据采集接口 |
IMq |
消息队列 |
消息队列消费者/生产者 |
IProducer / IConsumer |
消息队列 |
生产与消费消息 |
ISend / ISendUdp |
传输 |
通过 TCP/UDP 发送数据 |
ISendWait / ISendWaitUdp |
传输 |
发送并等待响应 |
ICommunication |
通信 |
客户端通信接口 |
ICommunicationService |
通信 |
服务端通信接口 |
ICreateInstance |
插件 |
驱动实例工厂 |
IGetParam / IGetStatus / IGetObject |
反射 |
内省接口 |
ILanguage / ILog |
基础设施 |
语言与日志 |
IOu |
数学 |
数学运算 |
IWA |
写入 |
写确认模式 |
IRemove |
删除 |
删除数据 |
特性 (7 种)
| 特性 |
用途 |
[Display] |
人类可读的名称显示 |
[Unit] |
测量单位标注 |
[Verify] |
输入验证规则 |
[AutoAllocating] |
自动地址分配 |
[AutoAllocatingTag] |
标签级自动分配 |
[ByteStructure] |
字节布局定义 |
[Multilingual] |
多语言字段标注 |
枚举 (8 种)
| 枚举 |
值数量 |
用途 |
DataType |
40 |
读/写操作的数据类型 |
QualityType |
-- |
数据质量指示 |
AddressType |
-- |
地址分类 |
EncodingType |
-- |
文本编码选择 |
DataFormat |
-- |
字节序(ABCD/BADC/CDAB/DCBA) |
LanguageType |
-- |
界面语言选择 |
ResponseType |
-- |
通信响应状态 |
PluginType |
-- |
插件分类 |
缓存系统
Snet.Core 提供两级缓存:
| 层级 |
位置 |
用途 |
| 进程缓存 |
应用程序内存 |
快速本地数据缓冲 |
| 共享内存缓存 |
操作系统共享内存 |
跨进程数据共享 |
性能注意事项
- 单例池限制: 255 个实例防止资源耗尽
- 事件传播: 使用异步事件避免阻塞发送线程
- 虚拟地址: 用于无硬件环境下的离线开发和测试
- 传输选择: TCP 追求可靠性,UDP 追求速度,WebSocket 用于 Web 集成
- Protobuf: 使用
AddressValueSimplify 提高网络序列化效率
技术支持
如有问题、功能需求或贡献意向,请参考项目内部文档和问题跟踪系统。