MQTT的websockets应用_转

时间:2021-03-20 16:48:01


转自: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