一、简介

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
using DDS.IoT.Com;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace DDS.IoT.Mqtt
{
public class MqttHostCom : ComBase
{
public override string Type => "mqttHostCom"; public override string Name => "Mqtt主机";
private MqttHostService hostService; public override bool Init(int port, int baudRate = 9600, string extendData = null)
{
this.Port = port;
hostService = new MqttHostService();
hostService.PushId = this.Id;
hostService.StartAsync(extendData, OnPushData);
Console.WriteLine("初始化MqttHostCom驱动程序成功!");
return true;
}
public override event PushData OnPushData; public override bool Open()
{
var b = false;
try
{
b = true;
IsOpen = true;
}
catch (Exception ex)
{ string msg = string.Format("MqttHostCom串口打开失败:{0} ", ex.Message);
Console.WriteLine(msg);
}
return b;
} public override bool Close()
{
hostService.Dispose();
hostService = null;
IsOpen = false;
OnPushData = null;
return true;
} public override string Command(string name, string data)
{
var outData = string.Empty; return outData;
}
}
}

    

  2.MqttClientCom 客户端

实现发布和订阅接口

using DDS.IoT.Com;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace DDS.IoT.Mqtt
{
public class MqttClientCom : ComBase
{
public override string Type => "mqttClientCom"; public override string Name => "Mqtt客户端";
private MqttClientService mqttClientService; public override bool Init(int port, int baudRate = 9600, string extendData = null)
{
mqttClientService = new MqttClientService();
mqttClientService.PushId = this.Id;
this.Port = port;
mqttClientService.MqttClientStart(extendData,this.OnPushData);
Console.WriteLine("初始化MqttClientCom驱动程序成功!");
return true;
}
public override event PushData OnPushData; public override bool Open()
{
var b = false;
try
{
mqttClientService.Open();
b = true;
IsOpen = true;
}
catch (Exception ex)
{ string msg = string.Format("MqttClientCom串口打开失败:{0} ", ex.Message);
Console.WriteLine(msg);
}
return b;
} public override bool Close()
{
mqttClientService.Close();
mqttClientService = null;
IsOpen = false;
OnPushData = null;
return true;
} public override string Command(string name, string data)
{
var outData = string.Empty; var dataObj = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(data);
switch (name)
{
case "Publish":
string topic = dataObj.topic;
string payload = dataObj.data;
int? level = dataObj.level;
bool? retain = dataObj.retain;
if (!level.HasValue)
{
level = 1;
}
if (!retain.HasValue)
{
retain = false;
}
outData =mqttClientService.Publish(topic, payload, level.Value, retain.Value).ToString();
break;
case "Subscribe":
topic = dataObj.topic;
level = dataObj.level;
if (!level.HasValue)
{
level = 0;
}
outData = mqttClientService.Subscribe(topic, level.Value).ToString();
break;
}
return outData;
}
}
}

3.前端测试

<!DOCTYPE HTML PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html>
<head lang="en">
<title>Mqtt</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
<meta name="format-detection" content="telephone=no">
<!-- Set render engine for 360 browser -->
<meta name="renderer" content="webkit">
<!-- No Baidu Siteapp-->
<!--<meta http-equiv="Cache-Control" content="no-siteapp" />-->
<META HTTP-EQUIV="pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate">
<META HTTP-EQUIV="expires" CONTENT="0">
<link rel="alternate icon" type="image/png" href="favicon.png">
<link rel="stylesheet" href="/scripts/amazeui/amazeui.min.css" />
<link rel="stylesheet" href="../css/main.css" />
<script src="/scripts/jquery-3.3.1.min.js"></script>
<script src="/scripts/amazeui/amazeui.min.js"></script> <script src="/scripts/jquery.signalR-2.4.1.min.js"></script>
<style>
.list {
width: 1000px !important;
} .am-form {
width: 100%;
background: #fff;
} .refresh-port {
width: 80px !important;
height: 30px !important;
} #msg, #msgWrite {
clear: both;
} .am-u-sm-4 {
padding: 3px;
}
</style>
<script type="text/javascript">
var hostid;// 主机id
var clientid;// 客户端id function startHost() {
var args = $('#txtHostArgs').val();
dds.iot.com.open({
type: 'mqttHostCom',//mqtt主机
port: 1,
baudRate: 1,
extendData: args,
//extendData: JSON.stringify({ server: "*", port: 1883 }),
onReceive: function (res) {
addMsg('host:' + JSON.stringify(res.data))
console.log('host', res.data)
},
onOpen: function (ar) {
if (ar.Success) {
hostid = ar.Data;
addMsg('连接成功!')
} else {
alert(ar.Message)
}
}
})
}
function closeHost() {
dds.iot.com.close(hostid)
}
function startClient() {
var args = $('#txtClientArgs').val();
dds.iot.com.open({
type: 'mqttClientCom',//mqtt客户端
port: 1,
baudRate: 1,
extendData: args,
//extendData: JSON.stringify({ server: "localhost", port: 1883, clientid: "1", username: "", password:""}),
onReceive: function (res) {
addMsg('client:' + JSON.stringify(res.data))
console.log('client',res.data)
},
onOpen: function (ar) {
if (ar.Success) {
clientid = ar.Data;
addMsg('连接成功!')
} else {
alert(ar.Message)
}
}
})
}
function subscribe() {
var topic = $('#txtTopic').val();
dds.iot.com.exeCommand({ id: clientid, name: "Subscribe", data: { topic: topic, level: 0 } }, function (ar) {
if (ar.Success) {
addMsg('订阅成功!')
} else {
addMsg('操作失败:' + ar.Message)
}
})
}
function publish() {
var topic = $('#txtTopic').val();
var contents = $('#txtContents').val();
dds.iot.com.exeCommand({ id: clientid, name: "Publish", data: { topic: topic, data: contents } }, function (ar) {
if (ar.Success) {
addMsg('发布成功!')
} else {
addMsg('操作失败:' + ar.Message)
}
})
}
function closeClient() {
dds.iot.com.close(clientid)
}
var $msg;
function addMsg(msg) {
$msg.val($msg.val()+"\n"+msg);
}
function clearLog() {
$msg.val('');
}
// 窗口初始化事件(操作窗口大小、标题)
$(document).bind('dds.window.init', function (e, win) {
$msg = $("#msg");
})
</script> </head> <body>
<div class="fun_bd" style="padding:10px;">
<form class="am-form">
<h3>数据读取</h3>
<fieldset>
<div class="am-form-group">
<label for="doc-ipt-email-1" class="am-u-sm-4">主机参数</label>
<div class="am-u-sm-6">
<input id="txtHostArgs" type="text" value='{ server: "*", port: 1883 }' />
</div>
<button onclick="startHost()" class="am-btn-primary" type="button">启动主机</button>
<button onclick="closeHost()" class="am-btn-danger" type="button">关闭主机</button>
</div>
<div class="am-form-group">
<label for="doc-ipt-email-1" class="am-u-sm-4">客户端参数</label>
<div class="am-u-sm-6">
<input id="txtClientArgs" type="text" value='{ server: "localhost", port: 1883, clientid: "1", username: "", password:""}' />
</div>
<button onclick="startClient()" class="am-btn-primary" type="button">启动客户端</button>
<button onclick="closeClient()" class="am-btn-danger" type="button">关闭客户端</button>
</div>
<div class="am-form-group">
<label for="doc-ipt-email-1" class="am-u-sm-4">主题</label>
<div class="am-u-sm-6">
<input id="txtTopic" type="text" value="/dds/iot/mqtt/test" />
</div>
<button onclick="subscribe()" class="am-btn-primary" type="button">订阅主题</button>
</div>
<div class="am-form-group">
<label for="doc-ipt-email-1" class="am-u-sm-4">主题内容</label>
<div class="am-u-sm-6">
<input id="txtContents" type="text" value="测试测试" />
</div>
<button onclick="publish()" class="am-btn-primary" type="button">发布主题</button>
</div> <!--<div id="msg"></div>-->
<textarea id="msg" rows="18"></textarea>
<div class="am-form-group">
<button onclick="clearLog()" class="am-btn-default" type="button">清除日志</button>
</div>
</fieldset>
</form>
</div> </body> </html>

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

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

 
 

物联网浏览器(IoTBrowser)-MQTT协议集成和测试的更多相关文章

  1. 海鑫智圣:物联网漫谈之MQTT协议

    什么是MQTT协议 MQTT(消息队列遥测传输协议)是IBM在1999年专门针对物联网等应用场景来制订的轻量级双向消息传输协议,它主要是为了解决物联网上使用到的设备的互相通信的问题,以及这些设备与后端 ...

  2. MQTT是IBM开发的一个即时通讯协议,构建于TCP/IP协议上,是物联网IoT的订阅协议,借助消息推送功能,可以更好地实现远程控制

    最近一直做物联网方面的开发,以下内容关于使用MQTT过程中遇到问题的记录以及需要掌握的机制原理,主要讲解理论. 背景 MQTT是IBM开发的一个即时通讯协议.MQTT构建于TCP/IP协议上,面向M2 ...

  3. 【转载】MQTT学习笔记——MQTT协议体验 Mosquitto安装和使用

    http://blog.csdn.net/xukai871105/article/details/39252653 0 前言     MQTT是IBM开发的一个即时通讯协议.MQTT是面向M2M和物联 ...

  4. 深度剖析MQTT协议的整个通信流程

    http://www.elecfans.com/d/587483.html MQTT,目前物联网的最主要的协议,基本所有收费的云平台都是基于MQTT协议,比如机智云,和所有的开放云平台比如中国移动的o ...

  5. MQTT协议学习研究 & Mosquitto简要教程(安装和使用)

    若初次接触MQTT协议,可先理解以下概念: [MQTT协议特点]——相比于RESTful架构的物联网系统,MQTT协议借助消息推送功能,可以更好地实现远程控制. [MQTT协议角色]——在RESTfu ...

  6. 物联网项目开发必读 深度分析MQTT协议优缺点

    物联网并不仅仅是一种网络,而是一个新的生态环境,它描述的本质是越来越多的使用物品通过网络连接在一起并可使用单个或者多个的终端设备对它们进行各种控制和使用—当然,工业上的物联网通常连接到的石鼓传感器或者 ...

  7. 转战物联网·基础篇09-选择MQTT协议还是CoAP协议

      前面章节介绍过,MQTT协议和CoAP协议都是物联网中比较流行的协议,都对传输量做了很大的精简,传输开销小,以适应物理网的网络环境.   XMPP协议也有人说是适合物联网通信的,但它是基于XML, ...

  8. 物联网MQTT协议分析和开源Mosquitto部署验证

    在<物联网核心协议—消息推送技术演进>一文中已向读者介绍了多种消息推送技术的情况,包括HTTP单向通信.Ajax轮询.Websocket.MQTT.CoAP等,其中MQTT协议为IBM制定 ...

  9. 【物联网云端对接-3】通过MQTT协议与微软Azure IoT Hub进行云端通信

    在上一篇文章<通过MQTT协议与阿里云物联网套件进行云端通信>中,我们介绍了通过MQTT对接阿里云的物联网套件.其实同样的代码,稍加调整也可以对接到微软Azure IoT hub上,不过需 ...

  10. 物联网网关MQTT应用与配置测试介绍

    1.MQTT介绍: MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),作为除Modbus外最常用的协议之一,因其基于发布/订阅的模式,具有资源消 ...

随机推荐

  1. 【Vue CLI】手把手教你撸插件

    本文首发于 vivo互联网技术 微信公众号链接:https://mp.weixin.qq.com/s/Rl8XLUX7isjXNUmbw0-wow作者:ZhuPing 现如今 Vue 作为主流的前端框 ...

  2. 如何在 Debian 12 上安装 MariaDB

    MariaDB 是一个开源多线程的关系数据库管理系统,是 MySQL 的替代品. MariaDB 是 Debian 中 MySQL 的默认替换方案. 本教程介绍如何在 Debian 12 上安装 Ma ...

  3. ​iOS Class Guard github用法、工作原理和安装详解及使用经验总结

    ​iOS Class Guard github用法.工作原理和安装详解及使用经验总结 iOS Class Guard是一个用于OC类.协议.属性和方法名混淆的命令行工具.它是class-dump的扩展 ...

  4. 【驱动】SPI驱动分析(四)-关键API解析

    关键API 设备树 设备树解析 我们以Firefly 的SPI demo 分析下dts中对spi的描述: /* Firefly SPI demo */ &spi1 { spi_demo: sp ...

  5. Java面试——基础知识点

    JVM Jvm体系总体分四大块:类的加载机制.Jvm内存结构.GC算法垃圾回收.GC分析命令调优. 类的加载机制 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的 ...

  6. 使用 Sealos 将 ChatGLM3 接入 FastGPT,打造完全私有化 AI 客服

    FastGPT 是一款专为客服问答场景而定制的开箱即用的 AI 知识库问答系统.该系统具备可视化工作流功能,允许用户灵活地设计复杂的问答流程,几乎能满足各种客服需求. 在国内市场环境下,离线部署对于企 ...

  7. Kubernetes: client-go 源码剖析(二)

    kubernetes:client-go 系列文章: Kubernetes: client-go 源码剖析(一) Kubernetes: client-go 源码剖析(二) 2.3 运行 inform ...

  8. 基于java+springboot的酒店预定网站、酒店客房管理系统

    该系统是基于Java的酒店客房预订系统设计与实现.是给师弟开发的毕业设计.现将源代码开放出来,感兴趣的同学可以下载. 演示地址 前台地址: http://hotel.gitapp.cn 后台地址: h ...

  9. 30-组合可编程逻辑器件-PLD

    组合可编程逻辑器件 1.PLD的结构 1.1 结构 1.2 表示方法 实心点表示连接,但是不可编程 ×点表示连接,但是可以编程 2.编程技术 2.1 熔丝工艺 每个输入线连接二极管和保险丝 2.2 电 ...

  10. 如何查看centos对于 TIME_WAIT 状态的 Socket 回收时间

    要查看系统对于 TIME_WAIT 状态的 Socket 回收时间,可以通过以下方式查询 TCP 数据结构中的相关字段值: cat /proc/sys/net/ipv4/tcp_fin_timeout ...