转自:mosquitto 与websocket 的结合

前言

mosquitto 作为一个消息代理, 客户端与 mosquitto 服务端的通信时基于 MQTT 协议的, 而现在的主流 web 应用时呈现在浏览器中, 这意味着用户与服务端只能通过 HTTP 或者 HTTPS 这类浏览器能理解的协议传输, 所以后端还要建立一个代理层, 将 HTTP 协议传输的内容解析一下以 MQTT 协议发送到 mosquitto, 最后再由 mosquitto 发送到硬件端。

在浏览器支持的协议中, 还有一个适用于长连接的 WS 协议, 参考: 浏览器中常见网络协议介绍。 如果客户端直接通过 websocket 连接到 mosquitto 端, 那么就不需要中间的后端代理层. 后端只需要一个推送服务和控制系统就可以实现对客户端的监听, 控制, 推送(当然, 如果业务量巨大, 业务逻辑复杂, 代理层还是有必要的, 因为这样不但可以为 mosquitto 过滤一些不必要的业务, 而且可以做一些数据统计, 设计事件钩子)。

在编译 mosquitto 和它的验证插件 mosquitto-auth-plug 的时候, 我注意到 mosquitto 有一个监听的 9001 端口, 事后查了一下, 发现 mosquitto 开放的这个端口是支持直接与客户端进行 websocket 通信的。

启用 mosquitto websocket 模式

其实纯粹的 MQTT 服务器是没有这个功能的, mosquitto 需要在编译的时候设置 configure.mk中

WITH_WEBSOCKETS := yes

所幸的是, eclipse 官方的 docker 镜像 已经支持了 websocket 通信方式. 只需要在 mosquitto.conf 中启用:

port 1883

listener 9001

protocol websockets

使用 paho-mqtt.js 通过 websocket 与 mosquitto 通信

eclipse 提供了用于 浏览器客户端利用 javascript 和 mosquitto 进行 websocket 通信的 paho-mqtt.js, 这是这个 js 库的文档: Paho.MQTT DOC.

客户端与服务端的双通道通信

我们假设有客户端用户为 client, 服务端用户为 server. 为他们分配的主题与权限为:

id | username | topic | rw

----+----------+--------------------+----

1 | client | /p/client/upload | 2

2 | server | /p/client/upload | 2

3 | client | /p/client/download | 1

4 | server | /p/client/download | 2

那么 server 和 client 均可以在 /p/client/upload 读写. 我们约定只有 client 在 /p/client/upload 写, server 只读 /p/client/upload, 这个 topic 是用于 client 向 server 发送消息.

对于 topic /p/client/download, server 可读可写, client 只读, 这个 topic 是用于 client 接受 server 向下推送的消息, 具体的逻辑如下:
aaarticlea/png;base64,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" alt="" name="图片 1" width="554" height="215" align="bottom" border="0" />

注意这里的
client
是对 /p/client/upload 具有可读可写权限的,
意味者它可以读取来自 /p/client/upload 的信息,
但是实际上这里没有人往这个主题发布消息(除非
client
自己往这里发消息),
所以
client
拥有可读权限也没有关系.

客户端的
javascript 通信例子

建议看一下这篇文章: Using
MQTT Over WebSockets with Mosquitto
,
它比较详细地介绍了客户端通过
websocket

mosquitto
服务器通信的方式.

比如对于 client.html:

先引入 paho-mqtt.js,
这里我们先用
cloudflare.com
CDN上的这段 js:

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.2/mqttws31.js"></script>

下面是创建客户端
websocket
的例子:

var mqtt;
var host = 'mosquitto';
var port = 9001; // onConnect 事件
function onConnect() {
console.log('connected.');
var raw_message = 'Hello World!';
message = new Paho.MQTT.Message(raw_message);
message.destinationName = '/p/client/upload';
console.log('sending message: ' + raw_message );
mqtt.send(message); // 订阅 download topic
var subOptions = {
qos: 1,
onSuccess: onSubscribe
};
mqtt.subscribe('/p/client/download', subOptions);
} // 订阅主题成功事件
function onSubscribe(context) {
console.log('subscribe success');
console.log(context);
} // 连接失败事件
function onFailure(message) {
console.log('connect failed.');
} // onMessageArrived 事件
function onMessageArrived(message) {
console.log('new message arrived...');
console.log(message.payloadString);
} // 建立 MQTT websocket 连接
function MQTTconnect() {
console.log('connecting to ' + host + ':' + port);
mqtt = new Paho.MQTT.Client(host, port, 'clientid');
var options = {
timeout: 3,
onSuccess: onConnect,
onFailure: onFailure,
userName: 'client',
password: '123456',
mqttVersion: 4
};
mqtt.onMessageArrived = onMessageArrived;
mqtt.connect(options);
}

这里我们利用 paho-mqtt.js 新建了一个 mqtt, 然后绑定 onSuccess(连接成功), onFailure(连接失败) onMessageArrived(消息到来)等事件, 之后用 options 里的配置连接到远程的 mosquitto 服务器. 连接成功后, client 向 server 发送一条消息到 /p/client/upload topic, 通知服务端已经建立连接. 发送之后 mqtt 又订阅 /p/client/download, 准备接受来自服务端的信息。

比如, 服务端可以这样向客户端推送消息:

import paho.mqtt.publish as publish
import time HOST = 'mosquitto'
PORT = 1883 if __name__ == '__main__':
client_id = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
publish.single(
'/p/client/download', 'hello mqtt', qos=2, hostname=HOST, port=PORT,
client_id=client_id, auth={'username': 'server', 'password': ''})

这就是基于双通道的服务端于客户端通信

客户端与服务端的单通道通信

单通道通信原理类似, 但是由于客户端可能有多台设备, 比如手机端, 微信小程序端, PC 端. 那么身份的验证不能直接由 mosquitto 确定, 应该在消息体内确定. 比如我们用 json 作为消息的承载方式. 消息体可以这样:

{
"timestamp": "",
"client_id": "",
"message_type": "ping",
"data": {"detail": "content"},
"token": "auth_token"
}

这里应该按照具体的业务需求进行鉴权设计。

参考:

    1. libwebsockets编译

    2. Using MQTT Over WebSockets with Mosquitto

MQTT的websockets应用_转的更多相关文章

  1. MQTT, XMPP, WebSockets还是AMQP?泛谈实时通信协议选型 good

    Wolfram Hempel 是 deepstreamIO 的联合创始人.deepstreamIO 是一家位于德国的技术创业公司,为移动客户端.及物联网设备提供高性能.安全和可扩展的实时通信服务.文本 ...

  2. Android开发笔记之《远程控制(MQTT|mosquitto) && (ProtocalBuffer | GRPC)》

    Android推送方案分析(MQTT/XMPP/GCM): http://www.open-open.com/lib/view/open1410848945601.htmlMQTT官网: http:/ ...

  3. MQTT进阶篇

            我们介绍了最流行的物联网协议MQTT的背景以及基本使用方法.在这篇文章中,我们会继续考察MQTT的高级玩法——与网页应用的交互.MQTT是基于TCP协议实现,基于HTTP的网页应用便无 ...

  4. [译] 你应该升级 MQTT3.1.1 的6个理由

    原文 6 facts why it’s worth upgrading to the brand new MQTT 3.1.1version 摘要:新版 MQTT 3.1.1 终于在 2014 年 1 ...

  5. Mosquitto安装_Ubuntu/Debian上安装消息队列Mosquitto

    Mosquitto安装_Ubuntu/Debian上安装消息队列Mosquitto MQTT是IBM开发的一个即时通讯协议.MQTT是面向M2M和物联网的连接协议,采用轻量级发布和订阅消息传输机制.M ...

  6. getting-started-with-mqtt

    来自:https://dzone.com/refcardz/getting-started-with-mqtt SECTION 1 Why MQTT? The Internet of Things ( ...

  7. mosquitto 配置文件解说

    #配置文件为mosquitto #参见mosquitto.conf(5)了解更多信息. #显示默认值,取消注释以更改. #使用#字符来表示注释,但只有当它是 #第一个字符就行了. #========= ...

  8. Excellent JD

    Job description About the role We are looking for a talented engineer who has excellent cloud skills ...

  9. ASYNCAPI

    https://www.asyncapi.com Introduction AsyncAPI provides a specification that allows you to define Me ...

随机推荐

  1. Nginx 配置 stream SSL 第四层 代理

    场景:服务器F针对访问终端需要添加白名单操作,由到终端数量较多,所以用了一台代理服务器 P,在服务F中添加 服务器P IP地址的白名单,所有终端访问服务器P 由于我已经安装过 Nginx 所以只需要添 ...

  2. [IR] Inverted Index & Boolean retrieval

    教材:<信息检索导论> 倒排索引 How to build Inverted Index? 1. Token sequence. 2. Sort by terms. 3. Dictiona ...

  3. PAT 甲级 1074 Reversing Linked List (25 分)(链表部分逆置,结合使用双端队列和栈,其实使用vector更简单呐)

    1074 Reversing Linked List (25 分)   Given a constant K and a singly linked list L, you are supposed ...

  4. Pytest单元测试框架-测试用例运行规则

    1.Pytest测试用例运行规则 在pytest单元测试框架下面执行用例,需要满足以下几个特点: 1. 文件名以test_*.py开头或者*_test.py 2. 测试类.测试函数以test开头 3. ...

  5. [LeetCode] 680. Valid Palindrome II 验证回文字符串 II

    Given a non-empty string s, you may delete at most one character. Judge whether you can make it a pa ...

  6. 【LeetCode】最长公共前缀【二分】

    编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...

  7. Apache Kafka + Spark Streaming Integration

    1.目标 为了构建实时应用程序,Apache Kafka  - Spark Streaming Integration是最佳组合.因此,在本文中,我们将详细了解Kafka中Spark Streamin ...

  8. Python-16-继承、封装、多态

    一.继承 1. 概念 继承是一种创建新类的方式,新建的类可以继承一个或多个父类(python支持多继承),父类又可称为基类或超类,新建的类称为派生类或子类. 子类会“”遗传”父类的属性,从而解决代码重 ...

  9. 数据分析-numpy的用法

    一.jupyter notebook 两种安装和启动的方式: 第一种方式: 命令行安装:pip install jupyter 启动:cmd 中输入 jupyter notebook 缺点:必须手动去 ...

  10. Crazy Binary String(前缀和)(2019牛客暑期多校训练营(第三场))

    示例: 输入: 801001001 输出:4 6 题意:一段长度为n且只有 ‘0’ 和 ‘1’ 的字符串,求子串中 ‘0’ 和 ‘1’ 数目相等和子序列中 ‘0’ 和 ‘1’ 数目相等的最大长度. 思 ...