Snet 文档

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(时间)
数组 BoolArrayByteArrayShortArray/Int16ArrayUShortArray/UInt16ArrayIntArray/Int32ArrayUIntArray/UInt32ArrayLongArray/Int64ArrayULongArray/UInt64ArrayFloatArray/SingleArrayDoubleArray

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 提高网络序列化效率

技术支持

如有问题、功能需求或贡献意向,请参考项目内部文档和问题跟踪系统。