Snet 框架 -- 协议驱动概览
最后更新: 2026-07-21
入口文件: Snet.Core/abstract/DaqAbstract.cs, Snet.Core/subscribe/SubscribeData.cs, Snet.Driver/
目标框架: .NET 8 / .NET 9 / .NET 10
架构
+----------------------------+
| 应用层 |
+-----------+----------------+
|
+-----------v----------------+
| Snet.Core (抽象层) |
| DaqAbstract<O, D> |
| CoreUnify<O, D> |
| SubscribeData.SCData |
+-----------+----------------+
|
+--------------------+--------------------+
| | |
+-------v-------+ +-------v-------+ +-------v-------+
| Snet.Modbus | | Snet.Siemens | | Snet.Mitsubishi|
| (TCP/UDP/RTU) | | (S7/PPI/FW) | | (MC/A-1E/A-3C)|
+---------------+ +---------------+ +---------------+
| | |
+-------v------------------------------------------------
| 33 种协议驱动 (PLC + 仪器仪表) |
+--------------------------------------------------------+
所有协议驱动均继承自 DaqAbstract<O, D>(其继承自 CoreUnify<O, D>),提供统一的单例生命周期管理,内置事件系统、日志、多语言、WebAPI 和订阅引擎。
核心模式
每个驱动仅由两个文件组成,遵循完全一致的架构:
1. 配置 -- {Vendor}Data.cs
namespace Snet.{Vendor}
{
public class {Vendor}Data
{
public class Basics : SubscribeData.SCData
{
public string SN { get; set; } = Guid.NewGuid().ToUpperNString();
public string? IpAddress { get; set; } // TCP 连接地址
public int Port { get; set; } // TCP 端口
public int Station { get; set; } // 站号 / 单元号
public string? SerialPortInfo { get; set; } // "COM3-9600-8-N-1"
public int ConnectTimeOut { get; set; }
public int ReceiveTimeOut { get; set; }
public ProtocolType ProtocolType { get; set; } // 枚举选择协议变体
// ... 供应商特定字段
}
public enum ProtocolType { /* 协议变体列表 */ }
}
}
Basics 继承 SubscribeData.SCData(提供 HandleInterval、ChangeOut、AllOut、TaskNumber)
ProtocolType 枚举携带 [AutoAllocating] 特性,可动态暴露与当前变体相关的配置字段
2. 实现 -- {Vendor}Operate.cs
namespace Snet.{Vendor}
{
public class {Vendor}Operate : DaqAbstract<{Vendor}Operate, {Vendor}Data.Basics>, IDaq
{
// 单例工厂方法
public static async Task<{Vendor}Operate> InstanceAsync(Basics config, CancellationToken token = default)
// 必须实现的 8 个抽象方法:
public override async Task<OperateResult> OnAsync(CancellationToken token)
public override async Task<OperateResult> OffAsync(bool hardClose, CancellationToken token)
public override async Task<OperateResult> ReadAsync(Address address, CancellationToken token)
public override async Task<OperateResult> WriteAsync(ConcurrentDictionary<string, (object, EncodingType?)> values, CancellationToken token)
public override async Task<OperateResult> SubscribeAsync(Address address, CancellationToken token)
public override async Task<OperateResult> UnSubscribeAsync(Address address, CancellationToken token)
public override async Task<OperateResult> GetStatusAsync(CancellationToken token)
public override async Task<OperateResult> GetBaseObjectAsync(CancellationToken token)
}
}
- 继承
DaqAbstract<Operate, Basics>,其继承自 CoreUnify<Operate, Basics>
- 自动获得:单例管理、事件总线(
OnDataEvent / OnInfoEvent)、WebAPI 宿主、日志、多语言
- 每个驱动实现全部 8 个抽象方法,将 Snet Address 模型翻译为供应商特定的通信协议
统一用法(所有驱动通用)
// 第一步: 配置 -- 所有驱动接口完全一致
var config = new ModbusData.Basics
{
IpAddress = "192.168.1.100",
Port = 502,
Station = 1,
ProtocolType = ModbusData.ProtocolType.ModbusTcpNet
};
// 第二步: 通过单例工厂实例化
var modbus = await ModbusOperate.InstanceAsync(config);
// 第三步: 打开连接
await modbus.OnAsync();
// 第四步: 读取 -- 使用统一的 Address 模型
var address = new Address(new AddressDetails("40001", DataType.Int16, length: 1));
var result = await modbus.ReadAsync(address);
// 第五步: 订阅持续轮询
await modbus.SubscribeAsync(address);
modbus.OnDataEvent += (sender, e) =>
{
if (e.Status && e.ResultData is AddressValue av)
Console.WriteLine($"40001 = {av.ResultValue}");
};
// 第六步: 写入
var writes = new ConcurrentDictionary<string, (object value, EncodingType? encodingType)>();
writes.TryAdd("40002", (42.5f, null));
await modbus.WriteAsync(writes);
// 第七步: 清理资源
await modbus.UnSubscribeAsync(address);
await modbus.OffAsync();
将 Modbus 替换为任意供应商名称(如 Siemens、Mitsubishi、Omron)-- API 接口完全一致。
完整驱动目录
欧美 PLC
| 包名 |
供应商 |
协议类型数 |
传输方式 |
主要变体 |
Snet.Siemens |
西门子 |
10 |
TCP / 串口 |
S7-200, S7-200Smart, S7-300, S7-400, S7-1200, S7-1500, FetchWrite, PPI, PPIOverTcp, S7Plus |
Snet.AllenBradley |
罗克韦尔 |
6 |
TCP / 串口 |
CIP, ConnectedCIP, Micro800, PCCC, SLC, DF1 |
Snet.Beckhoff |
倍福 |
1 |
TCP |
ADS |
Snet.GE |
通用电气 |
1 |
TCP |
SRTP |
日系 PLC
| 包名 |
供应商 |
协议类型数 |
传输方式 |
主要变体 |
Snet.Mitsubishi |
三菱 |
14 |
TCP / UDP / 串口 |
MC Binary/ASCII TCP/UDP, MC R, A-1E, A-3C, FX Serial/Links, CIP, Server 等 |
Snet.Omron |
欧姆龙 |
8 |
TCP / UDP / 串口 |
FINS TCP/UDP, CIP/ConnectedCIP, HostLink, HostLink C-Mode |
Snet.Keyence |
基恩士 |
5 |
TCP / 串口 |
MC Binary/ASCII, KV Nano Serial/TCP, KV Old |
Snet.Yaskawa |
安川 |
2 |
TCP / UDP |
Memobus TCP, Memobus UDP |
Snet.Yokogawa |
横河 |
1 |
TCP |
Link |
Snet.Fuji |
富士 |
4 |
TCP / 串口 |
SPH, SPB Serial/TCP, CommandSetting |
Snet.Panasonic |
松下 |
3 |
TCP / 串口 |
MC, Mewtocol Serial/TCP |
Snet.Toyota |
丰田 / 东洋 |
1 |
串口 |
Puc Serial |
Snet.OrientalMotor |
东方马达 |
1 |
TCP |
EIP |
国产 PLC
| 包名 |
供应商 |
协议类型数 |
传输方式 |
主要变体 |
Snet.Inovance |
汇川 |
6 |
TCP / 串口 |
TCP, Serial, SerialOverTcp, ComputerLink, ConnectedCIP, EasyNet |
Snet.XinJE |
信捷 |
4 |
TCP / 串口 |
TCP, Serial, SerialOverTcp, InternalNet |
Snet.Delta |
台达 |
5 |
TCP / 串口 |
TCP, Serial, SerialOverTcp, ASCII Serial, ASCII SerialOverTcp |
Snet.MegMeet |
麦格米特 |
3 |
TCP / 串口 |
TCP, Serial, SerialOverTcp |
Snet.Vigor |
丰炜 |
2 |
串口 |
Serial, SerialOverTcp |
Snet.WeCon |
维控 |
2 |
TCP / 串口 |
ModbusTCP, ModbusRTU |
Snet.Fatek |
永宏 |
2 |
串口 |
Serial, SerialOverTcp |
标准/通用协议
| 包名 |
协议 |
类型数 |
说明 |
Snet.Modbus |
Modbus |
6 |
TCP, UDP, RTU, RTUOverTcp, ASCII, ASCIIOverTcp -- 支持 30+ 功能码,使用最广泛的驱动 |
Snet.Opc |
OPC |
4 |
UA Client, UA Server, DA COM Client, DA HTTP Forward -- OPC 基金会标准 |
Snet.Freedom |
Freedom |
3 |
TCP, UDP, Serial -- 用户自定义自由协议 |
其他供应商驱动
| 包名 |
供应商 |
用途 |
Snet.Kossi |
Kossi / 高誓 |
韩系 PLC |
Snet.Cimon |
Cimon / 西盟 |
韩系 PLC |
Snet.LSis |
LS 电气 |
韩系 PLC |
Snet.Invt |
英威腾 |
国产 PLC / 变频器 |
Snet.Yamatake |
山武 / Azbil |
日系 PLC |
Snet.Turck |
图尔克 |
工业 I/O 模块 |
Snet.Fanuc |
发那科 |
机器人控制器 (CNC) |
Snet.PQDIF |
PQDIF |
IEEE 1159.3 电能质量数据交换格式 |
仪器仪表驱动
| 包名 |
标准 / 设备 |
用途 |
Snet.DLT645 |
DLT645-2007 / DLT645-1997 |
电表抄读 (国家电网) |
Snet.DLT698 |
DLT698 |
新一代电表标准 (中国) |
Snet.CJT188 |
CJT-188 |
水 / 气 / 热表抄读 |
Snet.IEC104 |
IEC 60870-5-104 |
电力远动 / SCADA |
Snet.RKC |
RKC 温控器 |
精密温度仪表 |
Snet.YuDian |
宇电温控器 |
工业温控仪表 |
Snet.DAM3601 |
DAM3601 |
数据采集模块 |
Snet.DTSU6606 |
DTSU6606 |
三相电能表 |
Address 地址模型 (所有驱动统一)
// 核心地址模型 -- 所有驱动使用相同的 Address 结构
var address = new Address(new AddressDetails(
addressName: "40001", // 供应商特定的地址字符串
dataType: DataType.Float, // DataType 枚举 (Int16, Float, Bool, String 等)
length: 2, // 读取多少个寄存器/字
encodingType: EncodingType.ASCII // 可选的编码提示
));
| 数据类型 |
C# 对应类型 |
典型大小 |
Bool / BoolArray |
bool / bool[] |
1 位 |
Byte / ByteArray |
byte / byte[] |
1 字节 |
Int16 / Int16Array |
short / short[] |
2 字节 |
UInt16 / UInt16Array |
ushort / ushort[] |
2 字节 |
Int32 / Int32Array |
int / int[] |
4 字节 |
UInt32 / UInt32Array |
uint / uint[] |
4 字节 |
Int64 / Int64Array |
long / long[] |
8 字节 |
UInt64 / UInt64Array |
ulong / ulong[] |
8 字节 |
Float / FloatArray |
float / float[] |
4 字节 |
Double / DoubleArray |
double / double[] |
8 字节 |
String |
string |
可变 |
Char |
char |
1-2 字节 |
内置 WebAPI
每个 DaqAbstract 驱动自动暴露 HTTP API:
| 端点 |
方法 |
负载 |
说明 |
/api/on |
POST |
无 |
打开连接 |
/api/off |
POST |
无 |
关闭连接 |
/api/read |
POST |
Address (JSON) |
读取单个地址 |
/api/write |
POST |
ConcurrentDictionary<string, WriteModel> |
写入多个地址 |
/api/getstatus |
GET |
无 |
获取连接状态 |
/api/switchlanguage |
GET |
无 |
切换 中文/英文 |
启用方式:
var wam = new WAModel { IpAddress = "0.0.0.0", Port = 5000 };
await modbus.WAOnAsync(wam);
订阅引擎
所有驱动通过 SubscribeData.SCData 继承内置订阅系统:
| 属性 |
默认值 |
说明 |
HandleInterval |
1000ms |
每个读取周期的轮询间隔 |
ChangeOut |
true |
仅在数据变化时触发事件 |
AllOut |
false |
ChangeOut 为 true 时,是否同时抛出变化项和未变项 |
TaskNumber |
5 |
并行轮询任务队列数量 |
传输层架构
+------------------+ +------------------+ +------------------+
| 串口 | | TCP 客户端 | | UDP |
| (RS-232/RS-485) | | | | (单播/组播/广播) |
+--------+---------+ +--------+---------+ +--------+---------+
| | |
+------------------------+--------------------------+
|
+-------------v-------------+
| Snet.Core 通信层 |
| Channel / Pipeline 层 |
+---------------------------+
| SerialOperate |
| TcpClientOperate |
| UdpClientOperate |
| UdpBroadcastOperate |
| UdpMulticastOperate |
+---------------------------+
每个驱动从核心通信层选择其传输方式,并用供应商特定的协议帧格式进行封装。
相关文档
- 中间件概览 -- MQTT, Kafka, RabbitMQ, NetMQ, Netty, TEP
- 中间件概览 (中文)
- Snet.Core 源码:
Snet.Core/abstract/DaqAbstract.cs
- Address 模型:
Snet.Model/data/Address.cs