基于IOT-Tree Server支持的gRPC服务,使用C#开发自己的设备监控客户端

1 gRPC介绍和缘起

gRPC 是一个高性能、开源的远程过程调用(RPC)框架,由 Google 开发并基于 HTTP/2 协议。它支持多种编程语言,并默认使用 Protocol Buffers(protobuf)作为接口定义语言(IDL)和数据序列化工具。gRPC 的设计目标是简化跨语言、跨平台的分布式系统开发。

gPRC可以支持多种编程语言(如 C++,C#, Java, Python, Go 等),通过 protobuf 实现接口定义的统一。并且有着性能优势:

  • 二进制编码(protobuf)比 JSON/XML 更高效。
  • HTTP/2 的多路复用减少连接开销。
  • 支持异步和非阻塞 I/O,适合高并发场景。

以上种种特点,使得gRPC成为现代分布式系统的理想选择,尤其适合性能敏感和复杂通信模式的场景。

1.1 IOT-Tree对gPRC的支持

IOT-Tree Server目前在内部实现了一个gRPC服务,通过protobuf接口定义和gRPC Server端实现,已经能够支持各种其他语言开发各自的客户端程序。由于IOT-Tree基于项目对设备接入数据做了统一(规整为标签Tag),所以客户端要对应的接口整体也就得到了极大的简化。

1.2 iottree.net开源项目

在官方开源项目 iottree.net 中,使用了C#实现了gRPC客户端调用封装,这更加简化了Api,可以让你很轻松的就可以完成基于IOT-Tree Server专有客户端。

本文就是以 开源项目 iottree.net为基础,讲述如何使用微软Visual Studio C#.NET 开发客户端。

1.3 优缺点

1 IOT-Tree Server在后台已经为你现场设备(如各种PLC)做好了对接,你要实现自己的客户端只需要支持IOT-Tree Server已经整理好的标签列表,每个标签使用类似 xxx.xx.xxx 格式的唯一路径标识。

这样你的客户端软件不需要考虑设备各种差异信息------如PLC中的数据地址等。这可以大大简化你的客户端开发过程。

2 使用gPRC可以使得一个IOT-Tree Server实例支持多个客户端同时访问,这在一些分布式管理现场会有很大的好处。

3 如果你运行的是单机系统,IOT-Tree Server和你的.net客户端程序运行在同一个系统中,这样可以达到最好的性能。

缺点:你的客户端程序必须配合IOT-Tree Server一起发布。

你如果对IOT-Tree Server还不了解,可以参考其他文章更多了解IOT-Tree能给你带来的好处:

使用IOT-Tree Server通过MC协议连接三菱Q系列PLC

使用IOT-Tree Server连接西门子PLC S7-300/1200/1500

使用IOT-Tree Server通过PPI(RS485)连接西门子PLC S7-200

系列文章还包含IOT-Tree完成一个具体项目的过程,非常详细,如下:

机房自动化监控手把手分享给你 - 10 项目完成总结

2 整体开发过程说明

2.1 IOT-Tree Server运行环境

我们还是以IOT-Tree Server中的Demo项目作为本文案例,你可以参考如下文档,快速搭建这个运行环境和项目:

快速开始https://gitcode.com/jasonzhu8888/iot-tree/blob/main/web/doc/cn/doc/quick_start.md

2.1.1 启用gRPC服务

上面的IOT-Tree Server运行实例和项目能够正常运行之后,你需要启用gPRC服务。在IOT-Tree Server管理主界面(非项目管理界面),点击服务程序(Services)里面的"设置Setup"按钮,在弹出的服务列表中,有个"gRPC Server"。如下图:

点击对应的"编辑"图标,在弹出的窗口中,使能此服务,并且选择你希望的对外服务端口,完成之后,就可以启动此service了。如下:

2.2 C#.Net开发说明

2.2.1 运行环境准备

微软Visual Studio开发环境,我这里就不说了,因为你能看到这里应该也熟悉相关技术。

访问下载 iottree.net 这个配套开源项目。使用微软Visual Studio软件打开工程。你可以看到里面有3个子项目。其中lib是使用c#对访问IOT-Tree Server的gRPC接口调用进行了封装,这样可以提供更直观简单的调用接口。另外两个是console demo和client demo。

你可以编译启动iottree_client_demo这个项目。界面如下:

你需要设置IOTTree Server gRPC地址和端口,且每个client都必须有自己的一个唯一id,以便于IOT-Tree Server区分不同的客户端。

Tag Path是此客户端需要监听同步和控制输出的标签列表,它的格式是 prj_name.xx.xx.tag_name。很明显,IOT-Tree Server中可以同时运行多个项目,而一个客户端可以同时监听多个项目中的数据标签。通过这种方式,可以发现IOT-Tree Server的客户端调用非常简单,只需要以这种唯一标签列表作为基础,而不需要考虑各种设备的复杂通信协议。因为这些复杂性都由IOT-Tree Server的项目给你搞定了。

点击按钮"Start Client",你可以发现正常连接成功之后,运行效果:

你可以通过下面的按钮控制水泵的启动和停止,也可以在右上角查看监听的标签数据更新变化情况。

2.2.2 iottree.net lib 封装库调用说明

你可以把lib库放到你的客户端项目中,主要涉及3个封装类IOTTreeClient,IOTTreeTagVal,IOTTreeTag。下面是此lib库如何调用的说明。

IOTTreeClient是客户端主封装类。调用非常简单:

创建对象,并设置需要监听的标签路径列表:

cs 复制代码
// create IOTTreeClient
client = new IOTTreeClient(url, clientid);
// tagpaths is List<string>
client.SetTagPaths(tagpaths);

由于标签路径是IOT-Tree Server项目中提供,你可以在IOT-Tree项目管理界面的标签列表进行导出复制,如图:

接下来我们就可以基于client对象提供的事件,进行监听并作后续处理:

cs 复制代码
client.StateChanged += (sender, e) =>
{
    ShowInf(false, $"State changed: {e.OldState} -> {e.NewState} ({e.Message})");
};

client.TagValueChanged += (sender, e) =>
{
    // Console.WriteLine($"Tag updated: {e.TagPath} = {e.Value} at {e.UpdateTime}");
    UpdateUI();
    IOTTreeTagVal tagval = e.TagVal;
    if (tagval.Path == "watertank.ch1.aio.wl_val")
    {
        UpdateWaterLvl(tagval);
    }
    if(tagval.Path== "watertank.ch1.dio.p_running")
    {
        //do something ....
    }
};

client.ConnectionLost += (sender, e) =>
{
    ShowInf(false, "Connection lost!");
};

client.ConnectionRestored += (sender, e) =>
{
    ShowInf(false, "Connection restored!");
};

client.ErrorOccurred += (sender, e) =>
{
    ShowInf(true, $"Error occurred: {e.Message}");
};

然后就可以启动或停止此client

cs 复制代码
client.Start();
client.Stop();

client启动正常连接IOT-Tree Server之后,你才能使用以下函数:

cs 复制代码
public IOTTreeTagVal GetTagValue(string tagPath);

public List<IOTTreeTagVal> GetTagValues();

public Dictionary<string, IOTTreeTagVal> GetTagValuesMap();

public List<IOTTreeTag> GetRegisterTags();

写或设置标签数据到IOT-Tree Server使用如下函数,这些函数都会触发单独的gRPC调用:

cs 复制代码
//write value to tag,it may cause device driver to do write operation
public async Task<bool> WriteTagValueAsync(string tagPath, string value);

//set tag value in memory
public async Task<bool> SetTagValueAsync(string tagPath, string value)

从IOT-Tree Server查询项目列表和项目下面的标签列表函数(会触发单独的gRPC调用):

cs 复制代码
public async Task<List<PrjItem>> ReadProjectListAsync() ;

public async Task<List<TagItem>> ReadTagsInProjectAsync(string projectName);

3 总结

从iottree.net提供的封装库Api看,整个调用过程非常简单。配合IOT-Tree Server的设备接入和数据组织,你可以把你的主要精力放在客户端展示功能的优化和美化上面------因为对客户端来说,围绕标签路径的就够了。

相关推荐
AC赳赳老秦2 小时前
等保2.0合规实践:DeepSeek辅助企业数据分类分级与自动化报告生成
大数据·人工智能·分类·数据挖掘·自动化·数据库架构·deepseek
骆驼爱记录2 小时前
Word表格题注自动设置全攻略
开发语言·c#·自动化·word·excel·wps·新人首发
想放学的刺客2 小时前
单片机嵌入式系统试题(第28期)flash芯片各引脚作用?低功耗设计估算电池续航时间是多少?如何优化低功耗等项目经验
stm32·单片机·嵌入式硬件·mcu·物联网·51单片机
Evonso3 小时前
视频转码与切片(HLS)完整教程
c#
搞科研的小刘选手3 小时前
【高质量|高届数学术会议推荐】第十三届先进制造技术与材料工程国际学术会议 (AMTME 2026)
自动化·制造·材料工程·新材料·先进制造技术·先进技术设计·制造系统
lfq7612043 小时前
.NET Framework 下 C# MVC 项目敏感信息安全存储方法
安全·c#·mvc·.net
m5655bj3 小时前
通过 C# 设置 Word 文档背景颜色、背景图
开发语言·c#·word
Blossom.1183 小时前
从“金鱼记忆“到“超级大脑“:2025年AI智能体记忆机制与MoE架构的融合革命
人工智能·python·算法·架构·自动化·whisper·哈希算法
杜子不疼.3 小时前
用Claude Code构建AI内容创作工作流:从灵感到发布的自动化实践
运维·人工智能·自动化