物联网浏览器(IoTBrowser)-MQTT协议集成和测试
一、简介
MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件 。
MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。

二、 开发插件
- 添加引用
- 添加MQTTNet,在NuGet搜索MQTTNet
- 添加Core,路径:\IoTBrowser\src\app_x64\Core.dll
- 添加Infrastructure,路径:\IoTBrowser\src\app_x64\Infrastructure.dll
- 添加Newtonsoft,路径:\IoTBrowser\src\app_x64\Newtonsoft.Json.dll
- 开发MqttHostCom和MqttClientCom插件
- 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协议集成和测试的更多相关文章
- 海鑫智圣:物联网漫谈之MQTT协议
什么是MQTT协议 MQTT(消息队列遥测传输协议)是IBM在1999年专门针对物联网等应用场景来制订的轻量级双向消息传输协议,它主要是为了解决物联网上使用到的设备的互相通信的问题,以及这些设备与后端 ...
- MQTT是IBM开发的一个即时通讯协议,构建于TCP/IP协议上,是物联网IoT的订阅协议,借助消息推送功能,可以更好地实现远程控制
最近一直做物联网方面的开发,以下内容关于使用MQTT过程中遇到问题的记录以及需要掌握的机制原理,主要讲解理论. 背景 MQTT是IBM开发的一个即时通讯协议.MQTT构建于TCP/IP协议上,面向M2 ...
- 【转载】MQTT学习笔记——MQTT协议体验 Mosquitto安装和使用
http://blog.csdn.net/xukai871105/article/details/39252653 0 前言 MQTT是IBM开发的一个即时通讯协议.MQTT是面向M2M和物联 ...
- 深度剖析MQTT协议的整个通信流程
http://www.elecfans.com/d/587483.html MQTT,目前物联网的最主要的协议,基本所有收费的云平台都是基于MQTT协议,比如机智云,和所有的开放云平台比如中国移动的o ...
- MQTT协议学习研究 & Mosquitto简要教程(安装和使用)
若初次接触MQTT协议,可先理解以下概念: [MQTT协议特点]——相比于RESTful架构的物联网系统,MQTT协议借助消息推送功能,可以更好地实现远程控制. [MQTT协议角色]——在RESTfu ...
- 物联网项目开发必读 深度分析MQTT协议优缺点
物联网并不仅仅是一种网络,而是一个新的生态环境,它描述的本质是越来越多的使用物品通过网络连接在一起并可使用单个或者多个的终端设备对它们进行各种控制和使用—当然,工业上的物联网通常连接到的石鼓传感器或者 ...
- 转战物联网·基础篇09-选择MQTT协议还是CoAP协议
前面章节介绍过,MQTT协议和CoAP协议都是物联网中比较流行的协议,都对传输量做了很大的精简,传输开销小,以适应物理网的网络环境. XMPP协议也有人说是适合物联网通信的,但它是基于XML, ...
- 物联网MQTT协议分析和开源Mosquitto部署验证
在<物联网核心协议—消息推送技术演进>一文中已向读者介绍了多种消息推送技术的情况,包括HTTP单向通信.Ajax轮询.Websocket.MQTT.CoAP等,其中MQTT协议为IBM制定 ...
- 【物联网云端对接-3】通过MQTT协议与微软Azure IoT Hub进行云端通信
在上一篇文章<通过MQTT协议与阿里云物联网套件进行云端通信>中,我们介绍了通过MQTT对接阿里云的物联网套件.其实同样的代码,稍加调整也可以对接到微软Azure IoT hub上,不过需 ...
- 物联网网关MQTT应用与配置测试介绍
1.MQTT介绍: MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),作为除Modbus外最常用的协议之一,因其基于发布/订阅的模式,具有资源消 ...
随机推荐
- KCD技术分享:以SBOM为基础的云原生应用安全治理
随着越来越多的企业和组织将他们的应用迁移到云上,云原生技术的应用部署和管理正在变得更加灵活和高效,但也相应地引入了一些新的安全风险.2023年4月15日,由云原生计算基金会(CNCF)发起,全球各国当 ...
- freeswitch上报信令到HOMER的配置方案
概述 HOMER是一款100%开源的针对SIP/VOIP/RTC的抓包工具和监控工具. 之前的文章中,我们介绍了HOMER的安装步骤,HOMER7的安装部署还是比较简单的,安装过程也比较顺利. 然后, ...
- 解决JedisNoReachableClusterNodeException,No reachable node in cluster报错
通过jedis连接redis集群时报如下的错误:JedisNoReachableClusterNodeException,No reachable node in cluster 本机连接均正常: ...
- 机器学习-决策树系列-决策树-ID3算法 -C4.5算法-26
目录 1. 决策树 2. 举个例子 计算信息增益 3. C4.5算法 1. 决策树 决策树是属于有监督机器学习的一种,起源非常早,符合直觉并且非常直观, 模型生成:通过大量数据生成一颗非常好的树,用这 ...
- spring--FactoryBean和BeanFactory有关系吗
BeanFactory 和 FactoryBean 是 Spring 框架中的两个不同的概念,两者是雷锋和雷峰塔的关系,就是没有任何关系,它们在 Spring 的依赖注入和 bean 创建过程中扮演不 ...
- Java21 + SpringBoot3整合Redis,使用Lettuce连接池,推荐连接池参数配置,封装Redis操作
目录 前言 相关技术简介 Redis 实现步骤 引入maven依赖 修改配置文件 定义Redis配置类 定义Redis服务类,封装Redis常用操作 使用Redis服务类 总结 前言 近日心血来潮想做 ...
- [转帖]tiup cluster restart
https://docs.pingcap.com/zh/tidb/stable/tiup-component-cluster-restart 注意 重启过程中会有一段时间服务不可用. 语法 tiu ...
- [转帖]DOCKER默认网段和主机网段冲突解决
https://www.cnblogs.com/yinliang/p/13189334.html 一. docker默认网卡docker0 172.17.0.0可能会与主机冲突,这时候需要修改dock ...
- [转帖]Kafka可靠性之HW与Leader Epoch
<深入理解Kafka:核心设计与实现原理>是基于2.0.0版本的书 在这本书中,终于看懂了笔者之前提过的几个问题 准备知识 1.leader里存着4个数据:leader_LEO.leade ...
- [转帖]AMD Zen4 霄龙 9004 转战嵌入式:192 框框无敌!秒杀对手 80%
http://www.myzaker.com/article/64104f50b15ec02eb10eb659 其实,它就是把此前用于服务器.数据中心的霄龙 9004 系列的部分型号拿了过来,命名.规 ...