经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » HTML/CSS » 浏览器 » 查看文章
物联网浏览器(IoTBrowser)-MQTT协议集成和测试
来源:cnblogs  作者:木子清  时间:2024/2/5 10:19:31  对本文有异议

一、简介

MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件 。

MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。

MQTT协议在物联网中应用广泛,下面使用插件式集成到IoTBrowser平台,提供JS API即可发布broker和客户端实现发布、订阅等功能。

二、 开发插件

  1. 添加引用
    1. 添加MQTTNet,在NuGet搜索MQTTNet
    2. 添加Core,路径:\IoTBrowser\src\app_x64\Core.dll
    3. 添加Infrastructure,路径:\IoTBrowser\src\app_x64\Infrastructure.dll
    4. 添加Newtonsoft,路径:\IoTBrowser\src\app_x64\Newtonsoft.Json.dll
  2. 开发MqttHostCom和MqttClientCom插件
    1. MqttHostCom 服务端 broker
  1. using DDS.IoT.Com;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO.Ports;
  5. using System.Linq;
  6. using System.Runtime.InteropServices;
  7. using System.Text;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. namespace DDS.IoT.Mqtt
  11. {
  12. public class MqttHostCom : ComBase
  13. {
  14. public override string Type => "mqttHostCom";
  15. public override string Name => "Mqtt主机";
  16. private MqttHostService hostService;
  17. public override bool Init(int port, int baudRate = 9600, string extendData = null)
  18. {
  19. this.Port = port;
  20. hostService = new MqttHostService();
  21. hostService.PushId = this.Id;
  22. hostService.StartAsync(extendData, OnPushData);
  23. Console.WriteLine("初始化MqttHostCom驱动程序成功!");
  24. return true;
  25. }
  26. public override event PushData OnPushData;
  27. public override bool Open()
  28. {
  29. var b = false;
  30. try
  31. {
  32. b = true;
  33. IsOpen = true;
  34. }
  35. catch (Exception ex)
  36. {
  37. string msg = string.Format("MqttHostCom串口打开失败:{0} ", ex.Message);
  38. Console.WriteLine(msg);
  39. }
  40. return b;
  41. }
  42. public override bool Close()
  43. {
  44. hostService.Dispose();
  45. hostService = null;
  46. IsOpen = false;
  47. OnPushData = null;
  48. return true;
  49. }
  50. public override string Command(string name, string data)
  51. {
  52. var outData = string.Empty;
  53. return outData;
  54. }
  55. }
  56. }

    

  2.MqttClientCom 客户端

实现发布和订阅接口

  1. using DDS.IoT.Com;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO.Ports;
  5. using System.Linq;
  6. using System.Runtime.InteropServices;
  7. using System.Text;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. namespace DDS.IoT.Mqtt
  11. {
  12. public class MqttClientCom : ComBase
  13. {
  14. public override string Type => "mqttClientCom";
  15. public override string Name => "Mqtt客户端";
  16. private MqttClientService mqttClientService;
  17. public override bool Init(int port, int baudRate = 9600, string extendData = null)
  18. {
  19. mqttClientService = new MqttClientService();
  20. mqttClientService.PushId = this.Id;
  21. this.Port = port;
  22. mqttClientService.MqttClientStart(extendData,this.OnPushData);
  23. Console.WriteLine("初始化MqttClientCom驱动程序成功!");
  24. return true;
  25. }
  26. public override event PushData OnPushData;
  27. public override bool Open()
  28. {
  29. var b = false;
  30. try
  31. {
  32. mqttClientService.Open();
  33. b = true;
  34. IsOpen = true;
  35. }
  36. catch (Exception ex)
  37. {
  38. string msg = string.Format("MqttClientCom串口打开失败:{0} ", ex.Message);
  39. Console.WriteLine(msg);
  40. }
  41. return b;
  42. }
  43. public override bool Close()
  44. {
  45. mqttClientService.Close();
  46. mqttClientService = null;
  47. IsOpen = false;
  48. OnPushData = null;
  49. return true;
  50. }
  51. public override string Command(string name, string data)
  52. {
  53. var outData = string.Empty;
  54. var dataObj = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(data);
  55. switch (name)
  56. {
  57. case "Publish":
  58. string topic = dataObj.topic;
  59. string payload = dataObj.data;
  60. int? level = dataObj.level;
  61. bool? retain = dataObj.retain;
  62. if (!level.HasValue)
  63. {
  64. level = 1;
  65. }
  66. if (!retain.HasValue)
  67. {
  68. retain = false;
  69. }
  70. outData =mqttClientService.Publish(topic, payload, level.Value, retain.Value).ToString();
  71. break;
  72. case "Subscribe":
  73. topic = dataObj.topic;
  74. level = dataObj.level;
  75. if (!level.HasValue)
  76. {
  77. level = 0;
  78. }
  79. outData = mqttClientService.Subscribe(topic, level.Value).ToString();
  80. break;
  81. }
  82. return outData;
  83. }
  84. }
  85. }

3.前端测试

  1. <!DOCTYPE HTML PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
  2. <html>
  3. <head lang="en">
  4. <title>Mqtt</title>
  5. <meta charset="UTF-8">
  6. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  7. <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
  8. <meta name="format-detection" content="telephone=no">
  9. <!-- Set render engine for 360 browser -->
  10. <meta name="renderer" content="webkit">
  11. <!-- No Baidu Siteapp-->
  12. <!--<meta http-equiv="Cache-Control" content="no-siteapp" />-->
  13. <META HTTP-EQUIV="pragma" CONTENT="no-cache">
  14. <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate">
  15. <META HTTP-EQUIV="expires" CONTENT="0">
  16. <link rel="alternate icon" type="image/png" href="favicon.png">
  17. <link rel="stylesheet" href="/scripts/amazeui/amazeui.min.css" />
  18. <link rel="stylesheet" href="../css/main.css" />
  19. <script src="/scripts/jquery-3.3.1.min.js"></script>
  20. <script src="/scripts/amazeui/amazeui.min.js"></script>
  21.  
  22. <script src="/scripts/jquery.signalR-2.4.1.min.js"></script>
  23. <style>
  24. .list {
  25. width: 1000px !important;
  26. }
  27. .am-form {
  28. width: 100%;
  29. background: #fff;
  30. }
  31. .refresh-port {
  32. width: 80px !important;
  33. height: 30px !important;
  34. }
  35. #msg, #msgWrite {
  36. clear: both;
  37. }
  38. .am-u-sm-4 {
  39. padding: 3px;
  40. }
  41. </style>
  42. <script type="text/javascript">
  43. var hostid;// 主机id
  44. var clientid;// 客户端id
  45.  
  46. function startHost() {
  47. var args = $('#txtHostArgs').val();
  48. dds.iot.com.open({
  49. type: 'mqttHostCom',//mqtt主机
  50. port: 1,
  51. baudRate: 1,
  52. extendData: args,
  53. //extendData: JSON.stringify({ server: "*", port: 1883 }),
  54. onReceive: function (res) {
  55. addMsg('host:' + JSON.stringify(res.data))
  56. console.log('host', res.data)
  57. },
  58. onOpen: function (ar) {
  59. if (ar.Success) {
  60. hostid = ar.Data;
  61. addMsg('连接成功!')
  62. } else {
  63. alert(ar.Message)
  64. }
  65. }
  66. })
  67. }
  68. function closeHost() {
  69. dds.iot.com.close(hostid)
  70. }
  71. function startClient() {
  72. var args = $('#txtClientArgs').val();
  73. dds.iot.com.open({
  74. type: 'mqttClientCom',//mqtt客户端
  75. port: 1,
  76. baudRate: 1,
  77. extendData: args,
  78. //extendData: JSON.stringify({ server: "localhost", port: 1883, clientid: "1", username: "", password:""}),
  79. onReceive: function (res) {
  80. addMsg('client:' + JSON.stringify(res.data))
  81. console.log('client',res.data)
  82. },
  83. onOpen: function (ar) {
  84. if (ar.Success) {
  85. clientid = ar.Data;
  86. addMsg('连接成功!')
  87. } else {
  88. alert(ar.Message)
  89. }
  90. }
  91. })
  92. }
  93. function subscribe() {
  94. var topic = $('#txtTopic').val();
  95. dds.iot.com.exeCommand({ id: clientid, name: "Subscribe", data: { topic: topic, level: 0 } }, function (ar) {
  96. if (ar.Success) {
  97. addMsg('订阅成功!')
  98. } else {
  99. addMsg('操作失败:' + ar.Message)
  100. }
  101. })
  102. }
  103. function publish() {
  104. var topic = $('#txtTopic').val();
  105. var contents = $('#txtContents').val();
  106. dds.iot.com.exeCommand({ id: clientid, name: "Publish", data: { topic: topic, data: contents } }, function (ar) {
  107. if (ar.Success) {
  108. addMsg('发布成功!')
  109. } else {
  110. addMsg('操作失败:' + ar.Message)
  111. }
  112. })
  113. }
  114. function closeClient() {
  115. dds.iot.com.close(clientid)
  116. }
  117. var $msg;
  118. function addMsg(msg) {
  119. $msg.val($msg.val()+"\n"+msg);
  120. }
  121. function clearLog() {
  122. $msg.val('');
  123. }
  124. // 窗口初始化事件(操作窗口大小、标题)
  125. $(document).bind('dds.window.init', function (e, win) {
  126. $msg = $("#msg");
  127. })
  128. </script>
  129.  
  130. </head>
  131.  
  132. <body>
  133. <div class="fun_bd" style="padding:10px;">
  134. <form class="am-form">
  135. <h3>数据读取</h3>
  136. <fieldset>
  137. <div class="am-form-group">
  138. <label for="doc-ipt-email-1" class="am-u-sm-4">主机参数</label>
  139. <div class="am-u-sm-6">
  140. <input id="txtHostArgs" type="text" value='{ server: "*", port: 1883 }' />
  141. </div>
  142. <button onclick="startHost()" class="am-btn-primary" type="button">启动主机</button>
  143. <button onclick="closeHost()" class="am-btn-danger" type="button">关闭主机</button>
  144. </div>
  145. <div class="am-form-group">
  146. <label for="doc-ipt-email-1" class="am-u-sm-4">客户端参数</label>
  147. <div class="am-u-sm-6">
  148. <input id="txtClientArgs" type="text" value='{ server: "localhost", port: 1883, clientid: "1", username: "", password:""}' />
  149. </div>
  150. <button onclick="startClient()" class="am-btn-primary" type="button">启动客户端</button>
  151. <button onclick="closeClient()" class="am-btn-danger" type="button">关闭客户端</button>
  152. </div>
  153. <div class="am-form-group">
  154. <label for="doc-ipt-email-1" class="am-u-sm-4">主题</label>
  155. <div class="am-u-sm-6">
  156. <input id="txtTopic" type="text" value="/dds/iot/mqtt/test" />
  157. </div>
  158. <button onclick="subscribe()" class="am-btn-primary" type="button">订阅主题</button>
  159. </div>
  160. <div class="am-form-group">
  161. <label for="doc-ipt-email-1" class="am-u-sm-4">主题内容</label>
  162. <div class="am-u-sm-6">
  163. <input id="txtContents" type="text" value="测试测试" />
  164. </div>
  165. <button onclick="publish()" class="am-btn-primary" type="button">发布主题</button>
  166. </div>
  167.  
  168. <!--<div id="msg"></div>-->
  169. <textarea id="msg" rows="18"></textarea>
  170. <div class="am-form-group">
  171. <button onclick="clearLog()" class="am-btn-default" type="button">清除日志</button>
  172. </div>
  173. </fieldset>
  174. </form>
  175. </div>
  176.  
  177. </body>
  178.  
  179. </html>

 

代码地址:https://gitee.com/yizhuqing/IoTBrowser

基于Chromium内核使用H5快速开发工控系统界面,使用JS API前端人员既可以完成界面展示与硬件控制。系统自带串口、RFID、电子秤等硬件协议支持,并且支持二次定制开发。可以用来开发人机界面(HMI)或数据采集与监督控制系统(SCADA) 。 使用H5或Vue可以本地打包离线应用,也可以在线加载Web网页来控制设备硬件。

 
 

原文链接:https://www.cnblogs.com/yizhuqing/p/18004476

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号