C#连接华为云平台IoTDA

  • 需求
  • 前期准备
  • 具体设计
    • 代码目录简述:
    • 工程配置参数
  • 具体程序
    • App.config
    • 主程序
      • 连接服务器
      • 接收到消息
      • 消息发布回调
      • 服务器连接成功
      • 断开服务器连接
    • 格式
  • 运行界面
  • 后续

需求

我们在平时的物联网开发中,往往需要用到云平台来收发数据。而光有云平台往往是不行的,我们还需要有上位机。那么怎样通过上位机连接到云平台,并且收发数据呢?本文将介绍如何通过C#编写的上位机和华为云平台通过物联网最常用MQTT协议进行连接并收发数据。介绍设备通MQTTS/MQTT协议接入平台,通过平台接口实现“数据上报”、“命令下发”的功能。

前期准备

  1. VS2019
  2. 华为云平台

具体设计

代码目录简述:

  1. App.config:Server地址和设备信息配置文件
  2. C#:项目C#代码;
  3. EncryptUtil.cs:设备密钥加密辅助类;
  4. FrmMqttDemo.cs:窗体界面;
  5. Program.cs:Demo程序启动入口。
  6. dll:项目中使用到了第三方库
  7. MQTTnet:v3.0.11,是一个基于 MQTT 通信的高性能 .NET 开源库,它同时支持MQTT 服务器端和客户端,引用库文件包含MQTTnet.dll。
  8. MQTTnet.Extensions.ManagedClient:v3.0.11,这是一个扩展库,它使用MQTTnet为托管MQTT客户机提供附加功能。

工程配置参数

App.config:需要配置服务器地址、设备ID和设备密钥,用于启动Demo程序的时
候,程序将此信息自动写到Demo主界面。

<add key="serverUri" value="serveruri"/>
<add key="deviceId" value="deviceid"/>
<add key="deviceSecret" value="secret"/>
<add key="PortIsSsl" value="8883"/>
<add key="PortNotSsl" value="1883"/>

具体程序

App.config

本文件中存放的是Server地址和设备信息配置文件,我们每个人的程序主要的不同就是这个文件,虽然后面也可以在运行的时候改,但最好提前写入。

<?xml version="1.0" encoding="utf-8"?>
<configuration><configSections></configSections><startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/></startup><appSettings><add key="serverUri" value="iot-mqtts.cn-north-4.myhuaweicloud.com"/><add key="deviceId" value="自己的设备ID"/><add key="deviceSecret" value="自己的设备密钥"/><add key="portIsSsl" value="8883"/><add key="portNotSsl" value="1883"/><add key="language" value="zh-CN"/></appSettings>
</configuration>

我们将自己的自己的设备ID和自己的设备密钥填入其中,选择相应的语言,最好填中文,毕竟看的方便。

主程序

连接服务器

             try{int portIsSsl = int.Parse(ConfigurationManager.AppSettings["portIsSsl"]);int portNotSsl = int.Parse(ConfigurationManager.AppSettings["portNotSsl"]);if (client == null){client = new MqttFactory().CreateManagedMqttClient();}string timestamp = DateTime.Now.ToString("yyyyMMddHH");string clientID = txtDeviceId.Text + "_0_0_" + timestamp;// 对密码进行HmacSHA256加密string secret = string.Empty;if (!string.IsNullOrEmpty(txtDeviceSecret.Text)){secret = EncryptUtil.HmacSHA256(txtDeviceSecret.Text, timestamp);}// 判断是否为安全连接if (!cbSSLConnect.Checked){options = new ManagedMqttClientOptionsBuilder().WithAutoReconnectDelay(TimeSpan.FromSeconds(RECONNECT_TIME)).WithClientOptions(new MqttClientOptionsBuilder().WithTcpServer(txtServerUri.Text, portNotSsl).WithCommunicationTimeout(TimeSpan.FromSeconds(DEFAULT_CONNECT_TIMEOUT)).WithCredentials(txtDeviceId.Text, secret).WithClientId(clientID).WithKeepAlivePeriod(TimeSpan.FromSeconds(DEFAULT_KEEPLIVE)).WithCleanSession(false).WithProtocolVersion(MqttProtocolVersion.V311).Build()).Build();}else{string caCertPath = Environment.CurrentDirectory + @"\certificate\rootcert.pem";X509Certificate2 crt = new X509Certificate2(caCertPath);options = new ManagedMqttClientOptionsBuilder().WithAutoReconnectDelay(TimeSpan.FromSeconds(RECONNECT_TIME)).WithClientOptions(new MqttClientOptionsBuilder().WithTcpServer(txtServerUri.Text, portIsSsl).WithCommunicationTimeout(TimeSpan.FromSeconds(DEFAULT_CONNECT_TIMEOUT)).WithCredentials(txtDeviceId.Text, secret).WithClientId(clientID).WithKeepAlivePeriod(TimeSpan.FromSeconds(DEFAULT_KEEPLIVE)).WithCleanSession(false).WithTls(new MqttClientOptionsBuilderTlsParameters(){AllowUntrustedCertificates = true,UseTls = true,Certificates = new List<X509Certificate> { crt },CertificateValidationHandler = delegate { return true; },IgnoreCertificateChainErrors = false,IgnoreCertificateRevocationErrors = false}).WithProtocolVersion(MqttProtocolVersion.V311).Build()).Build();}Invoke((new Action(() =>{ShowLogs($"{"try to connect to server " + txtServerUri.Text}{Environment.NewLine}");})));if (client.IsStarted){await client.StopAsync();}// 注册事件client.ApplicationMessageProcessedHandler = new ApplicationMessageProcessedHandlerDelegate(new Action<ApplicationMessageProcessedEventArgs>(ApplicationMessageProcessedHandlerMethod)); // 消息发布回调client.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(new Action<MqttApplicationMessageReceivedEventArgs>(MqttApplicationMessageReceived)); // 命令下发回调client.ConnectedHandler = new MqttClientConnectedHandlerDelegate(new Action<MqttClientConnectedEventArgs>(OnMqttClientConnected)); // 连接成功回调client.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(new Action<MqttClientDisconnectedEventArgs>(OnMqttClientDisconnected)); // 连接断开回调// 连接平台设备await client.StartAsync(options);}catch (Exception ex){Invoke((new Action(() =>{ShowLogs($"connect to mqtt server fail" + Environment.NewLine);})));}

接收到消息

Invoke((new Action(() =>{ShowLogs($"received message is {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}{Environment.NewLine}");string msg = "{\"result_code\": 0,\"response_name\": \"COMMAND_RESPONSE\",\"paras\": {\"result\": \"success\"}}";string topic = "$oc/devices/" + txtDeviceId.Text + "/sys/commands/response/request_id=" + e.ApplicationMessage.Topic.Split('=')[1];ShowLogs($"{"response message msg = " + msg}{Environment.NewLine}");var appMsg = new MqttApplicationMessage();appMsg.Payload = Encoding.UTF8.GetBytes(msg);appMsg.Topic = topic;appMsg.QualityOfServiceLevel = int.Parse(cbOosSelect.SelectedValue.ToString()) == 0 ? MqttQualityOfServiceLevel.AtMostOnce : MqttQualityOfServiceLevel.AtLeastOnce;appMsg.Retain = false;// 上行响应client.PublishAsync(appMsg).Wait();})));

消息发布回调

 try{if (e.HasFailed){Invoke((new Action(() =>{ShowLogs("publish messageId is " + e.ApplicationMessage.Id + ", topic: " + e.ApplicationMessage.ApplicationMessage.Topic + ", payload: " + Encoding.UTF8.GetString(e.ApplicationMessage.ApplicationMessage.Payload) + " is published fail");})));}else if (e.HasSucceeded){Invoke((new Action(() =>{ShowLogs("publish messageId " + e.ApplicationMessage.Id + ", topic: " + e.ApplicationMessage.ApplicationMessage.Topic + ", payload: " + Encoding.UTF8.GetString(e.ApplicationMessage.ApplicationMessage.Payload) + " is published success");})));}}catch (Exception ex){Invoke((new Action(() =>{ShowLogs("mqtt demo message publish error: " + ex.Message + Environment.NewLine);})));}

服务器连接成功

        Invoke((new Action(() =>{ShowLogs("connect to mqtt server success, deviceId is " + txtDeviceId.Text + Environment.NewLine);btnConnect.Enabled = false;btnDisconnect.Enabled = true;btnPublish.Enabled = true;btnSubscribe.Enabled = true;})));

断开服务器连接

        try {Invoke((new Action(() =>{ShowLogs("mqtt server is disconnected" + Environment.NewLine);txtSubTopic.Enabled = true;btnConnect.Enabled = true;btnDisconnect.Enabled = false;btnPublish.Enabled = false;btnSubscribe.Enabled = false;})));if (cbReconnect.Checked){Invoke((new Action(() =>{ShowLogs("reconnect is starting" + Environment.NewLine);})));//退避重连int lowBound = (int)(defaultBackoff * 0.8);int highBound = (int)(defaultBackoff * 1.2);long randomBackOff = random.Next(highBound - lowBound);long backOffWithJitter = (int)(Math.Pow(2.0, retryTimes)) * (randomBackOff + lowBound);long waitTImeUtilNextRetry = (int)(minBackoff + backOffWithJitter) > maxBackoff ? maxBackoff : (minBackoff + backOffWithJitter);Invoke((new Action(() =>{ShowLogs("next retry time: " + waitTImeUtilNextRetry + Environment.NewLine);})));Thread.Sleep((int)waitTImeUtilNextRetry);retryTimes++;Task.Run(async () => { await ConnectMqttServerAsync(); });}}catch (Exception ex){Invoke((new Action(() =>{ShowLogs("mqtt demo error: " + ex.Message + Environment.NewLine);})));}

格式

设备端上传到云平台
Topic:$oc/devices/{device_id}/sys/properties/report
数据格式:

数据格式:
{"services": [{"service_id": "Temperature","properties": {"smoke": 57,"temperature": 60,"humidity":78.37673},"event_time": "20151212T121212Z"}]
}

运行界面


当我发送如下数据时:

{"services": [{"service_id": "BS","properties": {"smoke": 57,"temperature": 60,"humidity":78.37673},"event_time": "20151212T121212Z"}]
}

后续

欢迎关注我的毕业设计专栏。
关注微信公众号,发送“C#连接华为云平台”获取源码。

编写不易,感谢支持。

C#编写上位机连接华为云平台IoTDA相关推荐

  1. HarmonyOS系统中内核实现MQTT连接华为云的方法

    大家好,今天主要和大家聊一聊,如何使用MQTT连接华为云平台的方法 目录 第一:MQTT通信基本原理 第二:华为IOT平台API 第三:华为IOT平台初始化 第四:设置命令响应函数 第五:数据上传 设 ...

  2. STM32通过NB(BC35-G)连接华为云IOT

    第一步:注册并绑定NB 注册账号之类的直接省略......直接从主题说起! 1.在自己已经建好的项目里面绑定NB模组: == *设备标识必须是NB模块的IMEI号(IMEI在芯片的丝印上)== 第二步 ...

  3. 台达DVP系列PLC如何通过RS485连接到华为云平台

    台达PLC是国产PLC品牌中的优质厂家,以高速.稳定.可靠而赢得消费者的喜爱,广泛应用于各种工业自动化设备,与旗下其他产品一样,都是具备扩展模块的功能,可以为不同企业的不同需求打造定制产品,因此,对于 ...

  4. 【教程】应用侧连接华为云IoT平台

    文章目录 1.写在前面 2.关于设备侧与华为云IoT平台的连接 3.进入华为云IoT平台 4.接收属性上报,实现数据转发至服务器 4.1.数据转发的总体实现思路 4.2.创建规则触发条件 4.3.创建 ...

  5. MQTT网关连接华为云物联网平台应用

    1.概述 ZLAN5143D是一款专门为工业环境设计的RS485设备数据采集器/物联网网关,兼具串口服务器.Modbus网关.MQTT网关.RS485转JSON等多种功能于一体.如图 1所示,可以连接 ...

  6. 【教程】ESP32连接华为云IoT平台

    目录 1前言 2应用侧接入华为云IoT平台 3必备环境 4使用步骤 4.1华为云IoT平台简介 4.2产品定义 4.3设备定义与注册 4.4ESP32编程接入 4.4.1头文件的包含 4.4.2接入参 ...

  7. OpenHarmony3.0如何轻松连接华为云IoT设备接入平台?

    摘要:本文主要介绍基于OpenHarmony 3.0版本来对接华为云IoT设备接入IoTDA,以小熊派BearPi-HM_Nano开发板为例,使用huaweicloud_iot_link SDK对接华 ...

  8. 设备如何使用go sdk轻松连接华为云IoT平台

    本文分享自华为云社区<设备如何使用go sdk轻松连接华为云IoT平台>,作者:华为云IoT专家团 . 本文介绍使用huaweicloud-iot-device-sdk-go 连接华为云I ...

  9. 使用MQTT连接华为云的物联网平台(二)

    使用MQTT连接华为云IOT平台 文章目录 使用MQTT连接华为云IOT平台 前言 一.MQTT.fx连接华为云需要什么 二.连接步骤 1.创建连接 2.订阅主题与发布主题 3.实践操作 总结 前言 ...

最新文章

  1. 实战测试SO_REUSEADDR选项
  2. 给你一份长长长的 Spring Boot 知识清单(下)
  3. 《剑指offer》答案整理
  4. 【Python】学习笔记总结(第二阶段(7-9)——汇总篇)
  5. 16进制的两位数转换不了 matlab_【大学生计算机基础】进制那些问题。小数或整数转换,各种进制间转换.........
  6. Centos7制作局域网http的yum源
  7. Python内置函数int()高级用法
  8. 【GoLang】GO语言系列--002.GO语言基础
  9. Linux之time命令
  10. 任务调度(三)——Timer的替代品ScheduledExecutorService简单介绍
  11. 聊聊运营商对UDP的QoS限制和应对
  12. 2016 工作、生活与得失
  13. 竖流式沉淀池三角堰计算_一种辐流式沉淀池的双侧堰出水构造的制作方法
  14. 分享 百度网盘,不用开会员也可以免费同步上传视频和照片的方法
  15. 【机器学习】机器学习公共数据集整理
  16. 深入浅出--何为多线程(引用自大神Kyrie lrving)
  17. Photoshop使用技巧
  18. Linux那些事儿之Linux sysfs -- 剖析版本虽旧,桃花依旧笑春风
  19. 美国国土安全部和MSF相继发布了Citrix漏洞的测试利用工具
  20. 商宝项目服务器,可照搬实施的商超高可用方案:proxmox + haproxy 等

热门文章

  1. java实现区块链中的区块hash难度系数的设计
  2. 计算机的基本键盘知识,知识:计算机键盘上每个键的功能_计算机的基本知识_IT /计算机_信息...
  3. nginx日志格式配置
  4. Multisim软件的基本使用
  5. 田野调查手记·浮山篇(一)
  6. JVM虚拟机概述(2)
  7. Conv2d函数详解(Pytorch)
  8. 微信小程序发现的一些小问题以及解决方案集合以及注意点
  9. CPU当中的分支预测
  10. swoole运行的时候提示端口被占用问题