【摘要】 .Net平台通过原生MQTT接口,作为南向设备对接OceanConnect平台

因为种种历史原因吧,目前华为平台上对.net的支持案例SDK确实比较少,当看到各种语言的SDK和Demo,唯独缺.net平台的,广大.net开发者也会怀疑.net是不是真的不适合IoT,甚至是互联网。

我的分析是

1、微软从.Net Framework开始所谓的跨平台,仅仅局限在Windows个版本的平台,对其他系统并不支持

2、微软多年以来给人的感觉是闭源,和Linux是死对头,在华为2019HC大会上和一位鲲鹏的工程师聊天也佐证了这一点,他们2019年了还依然对微软是这种认识

一提到开源,一提到互联网、分布式,.net就被轻视,这种态度很常见。

但是,我说的是但是,广大的.neter为什么选择.net平台的,为何mono这么多年都对.net跨平台不懈努力?为什么visual studio被称为宇宙第一的IDE?

那就是生产力。

以前的种种都成为历史了,自从.net core被提出,微软已经是一个亲Linux的代表了,跨平台、高性能已经是核心基础 。且不提Windows IoT, .net core在Linux,Arm上已经非常成熟了,树莓派们的小设备都能轻松玩转。

作为平台也好,工具也好就是为了提高生产力的。再来看看.net对接华为IoT平台,我现在从之前羡慕C/C++,Java,PHP等,在华为的帮助文档中都提供了南向设备的SDK,北向接口的SDK。我也一度怀疑华为为何不提供.net的SDK?没有SDK的帮助,对接将是比其他语言更要复杂,困难要一点点的肯。我也尝试在.net里用[DllImport]特性用c的sdk。

到现在,其实我可以负责任的告诉大家,.net根本不需要华为提供SDK,SDK本身对接口封装后就有不少限制,.net就利用公开的原始接口开发,非常简单和便捷,而且应用起来也灵活。这就是.net的强大生产力,而且.net framework(也可对接桌面程序)和.net core都可以实现。

1、北向接口对接

因为工作关系,对北向接口比较熟悉,华为提供的是restful的接口,和语言无关,实现起来轻车熟路。当时遇到一个困难就是用错了证书密码,现在回头看帮助文档中也说明了用哪个证书和密码,我也专门写过一个帖子来说明北向接口对接。

2、南向设备对接

南向设备比较复杂,对我来说确实是陌生的领域,小熊派这种MCU的板子恐怕只能有C来搞了,借助LiteOS+IoT Studio 也可以胜任。在我的计划中类似小熊派这样的设备甚至是定制更轻巧的,是物联网的常用终端类型。但还有些场景需要配合更丰富的应用,C恐怕做不到(起码需要带个界面啥的我做不到),或者说做到成本太高,在类似树莓派的独立设备,甚至是在Windows电脑上外接其他设备的场景,.net正是用武之地。

.Net core + Mqttnet 作为南向设备对接华为IoT平台

开发工具:Visual Studio 2019,.Net core 2.2和.net framework 4.7.2

Nuget包:MQTTnet 版本v3.0.8

核心内容三个事件

连接Mqtt服务器:

mqttClient.ConnectAsync(options);

订阅服务器Topic

var result = await mqttClient.SubscribeAsync(new TopicFilter()
{Topic = topicSubscribe,QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce});

服务器发送命令的响应

mqttClient.UseApplicationMessageReceivedHandler(async handle =>
{var payload = Encoding.Default.GetString(handle.ApplicationMessage.Payload);var data = JsonConvert.DeserializeObject<ReceivedMessage>(payload);Console.WriteLine($"收到MSG:{payload}");var result = await mqttClient.PublishAsync(topicPublish, $"{{\"msgType\":\"deviceRsp\",\"mid\":{data.Mid},\"errcode\":0,\"body\":{{\"response\":\"ok\"}}}}");Console.WriteLine($"设备响应命令:{result.ReasonCode}");
});

上报设备多信息到服务器:

var msg = new SendMessage
{Data = new List<Service>{new Service{ServiceData = new Dictionary<string, dynamic> { { "storage", st }, { "usedPercent", 10 }  },ServiceId = "Storage",EventTime = DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ")}}
};
var payload = JsonConvert.SerializeObject(msg, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
var result = await mqttClient.PublishAsync(topicPublish, payload);

完整代码如下:

using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Options;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Linq;
using MQTTnet.Client.Receiving;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using MQTTnet.Client.Subscribing;
using MQTTnet.Extensions.ManagedClient;
using System.Security.Cryptography;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;namespace CampusApp
{class Program{private static IMqttClient mqttClient;private static string topicPublish = "/huawei/v1/devices/00b1db5e-5331-4ade-8b62-6c670e6c8d98/data/json";private static string topicSubscribe = "/huawei/v1/devices/00b1db5e-5331-4ade-8b62-6c670e6c8d98/command/json";private static async Task ConnectMqttServerAsync(){if (mqttClient == null){mqttClient = new MqttFactory().CreateMqttClient();mqttClient.UseConnectedHandler(async handle =>{var result = await mqttClient.SubscribeAsync(new TopicFilter(){Topic = topicSubscribe,QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce});Console.WriteLine("连接成功");});mqttClient.UseApplicationMessageReceivedHandler(async handle =>{var payload = Encoding.Default.GetString(handle.ApplicationMessage.Payload);var data = JsonConvert.DeserializeObject<ReceivedMessage>(payload);Console.WriteLine($"收到MSG:{payload}");var result = await mqttClient.PublishAsync(topicPublish, $"{{\"msgType\":\"deviceRsp\",\"mid\":{data.Mid},\"errcode\":0,\"body\":{{\"response\":\"ok\"}}}}");Console.WriteLine($"设备响应命令:{result.ReasonCode}");});mqttClient.UseDisconnectedHandler(handle =>{Console.WriteLine($"MQTT 断开连接");});}var utctime =  DateTime.UtcNow.ToString("yyyyMMddhh");var pwd = Encrypt("9e4fbd64f6be2337732a", utctime);var options = new MqttClientOptionsBuilder().WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V311).WithClientId($"00b1db5e-5331-4ade-8b62-6c670e6c8d98_0_0_{utctime}").WithTcpServer("49.4.93.24", 8883).WithCredentials("00b1db5e-5331-4ade-8b62-6c670e6c8d98", pwd)//.WithKeepAlivePeriod(TimeSpan.FromSeconds(10)).WithKeepAliveSendInterval(TimeSpan.FromSeconds(3)).WithTls(new MqttClientOptionsBuilderTlsParameters(){AllowUntrustedCertificates = false,UseTls = true,Certificates = new List<byte[]> { new X509Certificate2("rootcert.pem").Export(X509ContentType.Cert) },CertificateValidationCallback = delegate { return true; },IgnoreCertificateChainErrors = false,IgnoreCertificateRevocatireplaceStrings = false}).WithCleanSession().Build();try{var result = await mqttClient.ConnectAsync(options);Console.WriteLine(result.ResultCode);}catch (Exception ex){Console.WriteLine(ex.Message);}}static string Encrypt(string message, string secret){secret = secret ?? "";//var encoding = new System.Text.ASCIIEncoding();var encoding = new System.Text.UTF8Encoding();byte[] keyByte = encoding.GetBytes(secret);byte[] messageBytes = encoding.GetBytes(message);using (var hmacsha256 = new HMACSHA256(keyByte)){byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);//return Convert.ToBase64String(hashmessage);StringBuilder rst = new StringBuilder();for (int i = 0; i < hashmessage.Length; i++){rst.Append(hashmessage[i].ToString("x2"));}return rst.ToString();}}static async Task Main(string[] args){try{_ = Task.Run(async () =>{await ConnectMqttServerAsync();});while (mqttClient?.IsConnected != true){await Task.Delay(1000);}while (true){Console.WriteLine("输入数字 storage:");var input = Console.ReadLine();if (!int.TryParse(input, out int st))continue;var msg = new SendMessage{Data = new List<Service>{new Service{ServiceData = new Dictionary<string, dynamic> { { "storage", st }, { "usedPercent", 10 }  },ServiceId = "Storage",EventTime = DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ")}}};var payload = JsonConvert.SerializeObject(msg, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });var result = await mqttClient.PublishAsync(topicPublish, payload);Console.WriteLine($"Publish Result: {result.ReasonCode}");}}catch (Exception ex){Console.WriteLine(ex.Message + ex.StackTrace);}}}
}

看这段代码多买的简单,就搞定了整个过程。

我在开发中重新整理了一下,作为一个SDK提供给.net framework和.net core两边使用,封装之后更加简单。完成之后作为nuget包再分享。

作者:神龙居市

.Net Core下使用MQTT协议直连IoT平台相关推荐

  1. QT使用MQTT协议对接华为IOT平台

    QT使用MQTT协议对接华为IOT平台文章目录QT使用MQTT协议对接华为IOT平台一.环境说明二.QMQTT源码编译三.对接华为IoT平台四.效果验证    最近想使用QT通过MQTT协议接入华为的 ...

  2. micropython mqtt_MicroPython使用MQTT协议接入OneNET云平台

    MicroPython使用MQTT协议接入OneNET云平台 [复制链接] 本帖最后由 hanyeguxingwo 于 2016-11-22 11:33 编辑 之前使用Arduino+ESP8266使 ...

  3. mqtt协议 阿里云物联网平台

    mqtt协议 阿里云物联网平台 MQTT报文结构 MQTT---CONNECT连接服务器报文 固定报头 可变报头 有效载荷 客户端ID 用户名 密码 转换 通过网络调试助手连接阿里云服务器 远程主机地 ...

  4. nvr linux 软件,Linux系统下运行RTSP协议安防视频平台EasyNVR出现安装服务错误,如何解决?...

    原标题:Linux系统下运行RTSP协议安防视频平台EasyNVR出现安装服务错误,如何解决? 大家知道TSINGSEE青犀视频云-边-端全线产品都是有两个不同系统的版本,分别是windows版本和l ...

  5. 技术实践丨手把手教你使用MQTT方式对接华为IoT平台

    摘要:本文主要讲述使用MQTT方式对接华为云IoT平台的具体过程. 使用的方案:目标板为STM32L431BearPI(带E53扩展板); TCPIP功能由开发板的ESP8266提供:MQTT使用Pa ...

  6. 移远BC20模组使用LwM2M协议接入华为IoT平台(NB-IoT专栏—进阶篇2)

    目录 1.背景 2.部署华为云 3.华为云与BC20模组进行数据收发实验 1.背景 最近在做一个智慧路灯项目,构思使用STM32结合NB-IoT模组实现数据上传和联动控制,并且可以使用GPS模块上传路 ...

  7. (过程超详细)适合新手的ATK-ESP8266+STM32F103系列单片机通过MQTT协议直连阿里云的教程

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.所用到的硬件设备 二.调试步骤 1.固件的烧录 2.创造阿里云的产品 3.代码修改 4.最终的硬件连接及效果图 总 ...

  8. 一文带你了解 MQTT 协议(连接 ONE-NET平台)

    MQTT 协议连接 ONE-NET 详解 写在前面 ​  本文采用 网络调试助手 发送MQTT协议报文(16进制) 连接 ONE-NET 平台,采用的 为 MQTT v3.1.1 标准协议.带你直接 ...

  9. 模块学习4:(1)通过MQTT协议和电信云平台的通信(内附MQTT协议V3.1.1的原版和中文参考资料)

    这里就不对MQTT协议本身作过多的讲解了,网上也有很多更加详细的对MQTT博文的讲解,当然更直接的就是参看协议文件. 这里直接贴一篇写的比较完整的博客和菜鸟教材对协议的讲解,可以参考学习. 菜鸟教程, ...

最新文章

  1. C# socket编程第二篇
  2. 第三次学JAVA再学不好就吃翔(part2)--基础语法之注释
  3. 数据结构之线段树合并——永无乡,Lomsat gelral,Tree Rotations,Tree Rotations Escape Through Leaf
  4. java json 修改字段_JSON文件-Java:编辑/更新字段值
  5. mysql 分片 数据迁移_简述MySQL分片中快速数据迁移_MySQL
  6. [fastjson] - fastjson中 JSONObject 和 JSONArray
  7. 微信潜规则:月薪过万的90后,过年都在看什么?
  8. 【技术分享】BurpSuite 代理设置的小技巧
  9. 免费织梦CMS文章采集器之采集聚合
  10. android 查看线程堆栈,firemonkey
  11. 从社区报告看未来20年美国AI研究战略
  12. 新冠病毒做进化树covidseq
  13. 路由器、DDNS、花生壳
  14. u盘安装系统win2019服务器系统,U盘启动装WIN10系统教程,U盘安装WIN2019方法,UltraISO将Windows server 2016/2019安装盘ISO写入U盘进行安装...
  15. 微信公众号获取AppID和AppSecret
  16. 实时音频编解码之四 LPC和LSF
  17. dc是什么游戏的简称_游戏缩写简称
  18. ##超市会员卡管理,利用我们之前的知识进行温习
  19. 兼容各操作系统平台的Anki选择题库模板
  20. NS3系列—3———NS3中文:4 概念描述

热门文章

  1. 视觉SLAM笔记(49) 后端状态估计
  2. 单片机应用中的c语言用词注解,单片机C语言程序注解
  3. quartz cron 每周一_quartz框架和关闭超时订单
  4. vue中下载excel的使用,后端链接两种情况,一个是链接,一个是文件流
  5. python默认参数不能定义为可变对象类型
  6. 机器学习入门一 ------- 什么是机器学习,机器学习的在实际中的用处
  7. centos7.3部署django用uwsgi和nginx[亲测可用]
  8. GitHub学习一-本地电脑与GitHub绑定
  9. svn://127.0.0.1/shop
  10. 分布式服务框架XXL-RPC