MQTT 和 WebSockets 并不是彼此的竞争关系,而是互补的。MQTT 是为物联网设计的(尽管当时并没有称之为物联网),而 WebSocket 协议则是为了给浏览器中的应用程序提供基于 TCP 的 socket API 访问,因此称为“WebSockets”。
MQTT 和 WebSockets都基于 TCP 连接运行,但 WebSocket 的功能更类似于 TCP 本身而不是 MQTT。一旦建立了 MQTT 连接,就可以通过该连接在两个方向上发送任意数量的消息,从传感器到后端,以及相反方向的命令。当与 MQTT 一起使用时,WebSocket 可以实现相同的行为,但代价是更高的开销。
我们这期重点分享下两者之间的异同,以及MQTT over Websockets的应用。
MQTT定义
MQTT(Message Queuing Telemetry Transport消息队列遥测传输)因其低带宽要求和可靠性,已成为物联网(IoT)应用的理想轻量级消息协议。
关于MQTT的详细解释,可以参考我们的专栏介绍:
#MQTT
WebSockets定义
WebSocket 是一种通信协议,通过单个 TCP 连接提供全双工通信通道,使客户端和服务器之间能够进行实时数据传输。
WebSocket 实现了客户端和服务器之间的直接通信通道,主要特征如下:
MQTT 与 WebSocket 比较总结
我们整理成下表所示:
MQTT 基于 TCP/IP 的架构是稳健的,但将其与 Websockets 结合使用,使其能够在需要通过单个连接实现双向通信的 web 浏览器和其他环境中有效运行。这种结合在需要持续连接而无需不断轮询的应用程序中(如实时更新、远程监控和实时数据流)越来越关键。
MQTT over WebSocket
将 MQTT 与 WebSocket 结合使用可以让开发人员利用两种协议的优势。这种集成特别适合基于 Web 的应用程序,其中 WebSocket 使 MQTT 能够在浏览器中高效运行,从而实现无缝和即时的数据交换。
由于 WebSockets 的行为类似于 TCP 套接字,因此可以在 WebSockets 上运行在 TCP 上运行的协议。现在有许多 MQTT 服务器和客户端库支持 WebSockets。最早提供支持的客户端库是那些在网页浏览器中运行的库,主要是 JavaScript,如下图所示:
有很多 IT 基础设施用于保护 HTTP 连接并阻止不必要的 TCP 流量。许多组织不愿意开放 MQTT 标准端口(1883 和 8883),以允许 MQTT 应用程序与组织内部的基础设施进行通信。WebSocket 协议允许 MQTT 通信使用现有的 HTTP 设施:TCP 端口 80、防火墙、代理等。因此,许多不运行在网页浏览器中的 MQTT 客户端库也支持 WebSocket,例如 Eclipse Paho C 客户端。
示例代码
import paho.mqtt.client as mqtt
# Callback when connected
defon_connect(client, userdata, flags, rc):
print(f"Connected with result code {rc}")
# Subscribe to topic
client.subscribe("sensors/temperature")
# Callback when message is received
defon_message(client, userdata, msg):
print(f"Received message on {msg.topic}: {msg.payload.decode()}")
# Create client
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
# Connect to broker
client.connect("mqtt.example.com", 1883, 60)
# Publish a message
client.publish("sensors/status", "online", qos=1, retain=True)
# Start network loop
client.loop_forever()
// Create WebSocket connection
const socket = newWebSocket('wss://example.com/socket');
// Connection opened
socket.addEventListener('open', (event) => {
console.log('Connected to WebSocket server');
// Send a message
socket.send(JSON.stringify({
type: 'status',
data: 'online'
}));
});
// Listen for messages
socket.addEventListener('message', (event) => {
const message = JSON.parse(event.data);
console.log('Received message:', message);
});
// Connection closed
socket.addEventListener('close', (event) => {
console.log('Disconnected from WebSocket server');
});
// Error handling
socket.addEventListener('error', (event) => {
console.error('WebSocket error:', event);
});
// Using the MQTT.js library
const client = mqtt.connect('wss://mqtt.example.com:8884/mqtt', {
clientId: 'browser_client_' + Math.random().toString(16).substr(2, 8),
username: 'username',
password: 'password'
});
// Handle connection
client.on('connect', function () {
console.log('Connected to MQTT broker over WebSocket');
// Subscribe to topics
client.subscribe('sensors/temperature');
// Publish a message
client.publish('sensors/status', 'online from browser', {
qos: 1,
retain: true
});
});
// Handle incoming messages
client.on('message', function (topic, message) {
console.log(`Received message on ${topic}: ${message.toString()}`);
});
// Handle errors
client.on('error', function (error) {
console.error('MQTT error:', error);
});
结论
MQTT 和 WebSocket 用途不同,但也可以一起工作:
在选择这些技术时,请考虑您对消息路由、投递保证、客户端平台和网络限制的具体要求。在许多情况下,您甚至可以在架构的不同部分同时使用这两种协议。
参考链接: