前言
工业物联网这个领域,有个老难题一直没解决好:不同厂家的设备说不同的协议。西门子PLC讲S7协议,施耐德用Modbus,高端设备可能走OPC UA,边缘端还有一堆MQTT设备。以前的做法是针对每种协议单独写一套采集程序,最后运维手里攒了一堆"小工具",改个配置都得翻半天代码。
本文推荐这个框架的思路不太一样——它把设备通信这件事抽象成统一的读写模型,上层业务代码面对的不再是千奇百怪的协议,而是一个简单的Request/Response接口。
项目介绍
一个基于.NET 10 开发的工业物联网通讯集成框架,主打高性能和插件化。它的核心定位是充当工业设备(南向)和IT系统(北向)之间的协议转换桥梁。
不管你底下接的是西门子PLC、OPC UA服务器,还是Modbus设备、MQTT Broker,到UniCon这一层都变成了统一的调用方式。框架内置了v2极速扫描引擎、智能自愈机制、Quartz任务调度和动态WebAPI,单机可支撑万级点位的高频轮询。
项目功能
功能模块 | 具体能力 | 适用场景 |
统一读写契约 | UniconRequest/Response抽象模型,屏蔽底层协议差异 | 多协议设备统一接入 |
v2扫描引擎 | 基于Channel异步分发与无锁队列,支持万级点位高频采集 | 大规模设备数据采集 |
智能自愈 | Watchdog监控+指数退避重连,自动处理网络中断 | 工业现场恶劣网络环境 |
任务调度 | Quartz.NET集成,支持CRON表达式配置采集任务 | 批处理、定时巡检 |
动态WebAPI | Minimal API运行时注册,提供标准RESTful接口 | 第三方系统调用设备数据 |
数据质量审计 | DataValue自带Quality戳和ServerTimestamp | 时序数据库数据清洗 |
插件化驱动 | 基于DriverBase基类,新增协议只需实现读写逻辑 | 扩展新设备类型 |
变化订阅 | ExceptionBased模式,仅值变化时推送,支持死区过滤 | 降低网络与存储压力 |
项目特点
协议抽象得干净
最出彩的设计是那个统一的读写契约。不管你是读PLC的DB块,还是查OPC UA的节点,甚至是从MQTT拉一条消息,在上层看起来都像是在调一个HTTP接口。这种设计借鉴了现代Web架构的思路,熟悉RESTful风格的人几乎没有学习成本。
v2引擎下了功夫
很多物联网框架的痛点不是功能不够,而是扛不住并发。项目的v2扫描引擎用System.Threading.Channels做异步分发,搭配无锁队列设计,把调度、地址合并去重、回调推送这三个环节彻底解耦。实测在万级点位的高频采集场景下,CPU和内存的表现都比较克制。
自愈机制很务实
工业现场的网络环境大家都懂——交换机重启、网线松了、PLC临时离线,这些是家常便饭。UniCon内置的Watchdog加指数退避重连算法,能自动感知链路状态并尝试恢复,不用写一堆重试的胶水代码。
插件化不玩虚的
新增一个协议驱动,继承DriverBase基类,实现核心读写逻辑就行。框架会通过依赖注入自动发现和注册驱动,不用改核心代码。目前官方已经提供了S7、OPC UA、Modbus、MQTT四套生产级驱动,基本覆盖了主流场景。
数据质量原生支持
DataValue< T>这个领域模型带Quality和ServerTimestamp字段,专门适配时序数据库(如InfluxDB、TDengine)对数据源头审计的要求。这个细节说明框架的设计者对工业场景的真实需求有了解——光有数值不够,还得知道这个值可不可信、是什么时候采集的。
项目技术
技术分层 | 具体技术 | 用途说明 |
运行时 | .NET 10.0 (C# 14/15) | 框架基础运行环境 |
依赖注入 | Microsoft.Extensions.DependencyInjection | 模块化与服务注册 |
Web框架 | ASP.NET Core Minimal APIs | 动态RESTful接口暴露 |
高并发 | System.Threading.Channels | 异步无锁队列,v2引擎核心 |
任务调度 | Quartz.NET | CRON表达式定时任务 |
参数验证 | FluentValidation | 请求参数校验 |
配置管理 | Options Pattern | 强类型配置绑定 |
S7驱动 | S7netplus | 西门子PLC通信 |
OPC UA驱动 | Workstation.UaClient | OPC UA客户端 |
Modbus驱动 | EasyModbusTCP | Modbus TCP/RTU |
MQTT驱动 | MQTTnet | 消息队列客户端 |
项目代码
安装使用非常简单。首先按需安装NuGet包:
# 核心包(必装)dotnet add package xxxx.Core# 按需装驱动,比如接西门子PLC就装这个dotnet add package xxxx.Drivers.S7然后在Program.cs中注册服务:
using xxxx.Core.Extensions;var builder = WebApplication.CreateBuilder(args);// 一键注册UniCon核心builder.Services.AddUniCon();// 可选:注册Quartz调度builder.Services.AddQuartzService();var app = builder.Build();app.Run();连接设备并订阅点位变化:
// 实例化西门子驱动var s7Driver = new S7Driver("Siemens_PLC_01", logger, cacheProvider);s7Driver.EnableAutoReconnect = true;// 连接PLCawait s7Driver.ConnectAsync("CpuType=S71200;Ip=192.168.1.200;Rack=0;Slot=1");// 订阅点位,变化时回调var subscriptionId = await s7Driver.SubscribeAsync(new UniconSubscription{ Address = "DB10.DBD20", ScanRateMs = 200, ScanMode = UniconScanMode.ExceptionBased, // 仅变化推送 Metadata = new TagMetadata { Deadband = 0.2, Unit = "Mpa" }, Callback = async dataValue => { Console.WriteLine($"当前值: {dataValue.Value} {dataValue.Unit}"); }});通过HTTP接口读取设备数据:
GET http://localhost:5000/api/drivers/Siemens_PLC_01/read?address=DB10.DBD20返回结果示例:
{ "success": true, "code": 200, "data": { "address": "DB10.DBD20", "value": 12.84, "quality": "Good", "serverTimestamp": "2026-05-23T17:24:28.104Z" }}项目效果
多品牌设备统一接入:车间里有西门子PLC、第三方的Modbus仪表、还有几个OPC UA接口的机器人,以前需要三套采集程序。用UniCon一套框架全搞定,上层MES系统调统一接口就行。
高频数据采集:v2引擎的Channel设计适合振动监测、高速包装线这类需要毫秒级轮询的场景。官方文档提到万级点位的并发采集能力,实际性能取决于硬件配置,但架构层面没有明显瓶颈。
协议扩展:碰到非标准协议或者定制设备,写一个驱动插件就行。框架提供的DriverBase基类已经把连接管理、重连、日志这些通用逻辑封装好了,只需要实现ReadAsync/WriteAsync两个核心方法。
时序数据入库:DataValue自带的Quality和ServerTimestamp字段,接InfluxDB时可以直接落库,后续做数据清洗和分析都有据可查。
项目源码
目录结构
xxx/├── src/│ ├── xxxx.Core/ # 核心抽象与领域模型│ ├── xxxx.Drivers.S7/ # 西门子S7驱动│ ├── xxxx.Drivers.OpcUa/ # OPC UA驱动│ ├── xxxx.Drivers.Modbus/ # Modbus驱动│ ├── xxxx.Drivers.Mqtt/ # MQTT驱动│ ├── xxxx.WebServer/ # WebAPI宿主网关│ └── xxxx.Jobs/ # Quartz任务扩展├── tests/ # 单元测试└── .vuepress_docs/ # 在线文档工程快速启动:
git clone https://github.com/entity/xxxx.gitcd xxxxdotnet restoredotnet build -c Releasedotnet run --project src/xxxx.WebServer服务启动后访问 http://localhost:5000/health 检查健康状态。
为了防止丢失,可以在评论区留言关键字「工业物联网」,即可获取完整源码地址。
总结
项目给人的印象是一个"懂工业"的框架。它没有盲目追求新潮的技术栈,而是在协议抽象、并发调度、自愈机制这些实实在在的痛点上深耕。统一读写契约的设计思路值得学习——复杂系统里做抽象,收益往往比想象的大。v2引擎基于Channel的实现也提供了一个高并发调度的参考范例。
不过目前这个项目还很新,驱动覆盖面还有提升空间,比如CANopen、Profinet这些工业现场常见的协议还没有官方驱动。如果团队正好在搞工业物联网平台,值得花时间研究一下,至少那个插件化架构和统一读写模型,能帮你省不少重复造轮子的功夫。
关键词
最后
如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。也可以加入微信公众号[DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!
作者:小码编匠
出处:gitee.com/smallcore/DotNetCore
声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!
方便大家交流、资源共享和共同成长
纯技术交流群,需要加入的小伙伴请扫码,并备注【加群】
推荐阅读
觉得有收获?不妨分享让更多人受益
关注「DotNet技术匠」,共同提升技术实力
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!