MQTT 与 WebSocket 的结合是物联网场景中非常常见的方案,核心是让 MQTT 协议运行在 WebSocket 之上 (即 MQTT over WebSocket),既保留 MQTT 轻量、适合设备通信的特性,又利用 WebSocket 的浏览器 / 网页端友好性,同时解决了部分网络环境下仅允许 HTTP/WebSocket 端口通行的问题。以下从结合原理、部署实现、使用场景三个维度详细说明:
一、MQTT 与 WebSocket 结合的核心原理
MQTT 原本是基于TCP/IP的应用层协议,而 WebSocket 是在 HTTP 基础上建立的双向长连接协议,二者的结合本质是:
- 协议封装:将 MQTT 的数据包封装在 WebSocket 的帧中进行传输,WebSocket 作为 "传输通道",MQTT 作为 "应用层逻辑";
- 端口复用:WebSocket 默认使用 80(ws://)或 443(wss://)端口,这些端口通常不会被防火墙 / 路由器拦截,解决了传统 MQTT 的 1883(TCP)/8883(SSL/TCP)端口被屏蔽的问题;
- 双向通信:二者均为长连接、双向通信,完美匹配物联网设备实时上报状态、服务器下发指令的需求。
简单来说:WebSocket 负责 "打通网络通道",MQTT 负责 "定义设备通信的规则" 。
二、具体实现方式(以主流的 EMQX 为例)
EMQX 是开源的高性能 MQTT Broker,原生支持 MQTT over WebSocket,是物联网场景的首选,以下是从服务端配置、客户端接入的完整实现步骤:
1. 服务端:配置 EMQX 支持 MQTT over WebSocket
EMQX 默认开启了 WebSocket 监听,无需复杂配置即可使用,关键参数可参考:
-
默认端口:
- 非加密 WebSocket(ws://):8083 端口(对应 MQTT TCP 的 1883);
- 加密 WebSocket(wss://):8084 端口(对应 MQTT TCP 的 8883);
-
验证配置 :打开 EMQX 的配置文件(
emqx.conf),确认 WebSocket 监听器已启用:ini# 启用WebSocket监听器 listeners.ws.default { bind = "0.0.0.0:8083" max_connections = 1024000 # 最大连接数 } # 启用WSS(加密)监听器 listeners.wss.default { bind = "0.0.0.0:8084" ssl_options { certfile = "/etc/emqx/certs/emqx.pem" keyfile = "/etc/emqx/certs/emqx.key" } } -
启动 EMQX :启动后可通过 EMQX Dashboard(默认http://localhost:18083)查看 WebSocket 连接状态,确认监听器正常运行。
2. 客户端接入:设备 / 前端通过 WebSocket 连接 MQTT Broker
根据客户端类型(嵌入式设备、网页前端、后端服务),有不同的接入方式,核心是使用支持 MQTT over WebSocket 的客户端库。
(1)网页前端(浏览器)接入(最常见场景)
浏览器本身不支持原生 MQTT,但可通过 WebSocket 连接 EMQX 的 8083 端口,使用 MQTT 客户端库(如mqtt.js)实现通信:
-
安装依赖:
cssnpm install mqtt --save -
代码示例:
javascript
运行
javascriptimport mqtt from 'mqtt'; // 连接配置:WebSocket地址格式为 ws://broker地址:8083/mqtt const client = mqtt.connect('ws://localhost:8083/mqtt', { clientId: 'web-client-123', // 唯一客户端ID username: 'admin', // 可选,EMQX默认用户名 password: 'public', // 可选,EMQX默认密码 keepalive: 60, // 心跳间隔(秒) }); // 连接成功回调 client.on('connect', () => { console.log('WebSocket + MQTT 连接成功'); // 订阅设备状态主题 client.subscribe('device/aircon/status', (err) => { if (!err) console.log('订阅成功'); }); // 发布指令(控制空调) client.publish('device/aircon/control', JSON.stringify({ temp: 26 })); }); // 接收消息回调 client.on('message', (topic, payload) => { console.log(`收到主题 ${topic} 的消息:${payload.toString()}`); });关键注意 :WebSocket 的 URL 路径必须是
/mqtt(EMQX 等 Broker 的约定),否则会连接失败。
(2)嵌入式设备接入(如小米空调 / 电视)
嵌入式设备(如基于 ESP32、Linux 的智能设备)可使用 MQTT 客户端库(如paho-mqtt、emqx-mqtt-c),通过 WebSocket 协议连接 Broker:
-
以 C 语言的
emqx-mqtt-c为例,核心配置:scss#include "emqx_mqtt_c.h" int main() { // 连接参数:指定WebSocket协议,端口8083 mqtt_client_t client; mqtt_client_init(&client); mqtt_client_set_port(&client, 8083); mqtt_client_set_protocol(&client, MQTT_PROTOCOL_WS); // 启用WebSocket mqtt_client_set_host(&client, "localhost"); mqtt_client_set_client_id(&client, "device-aircon-456"); // 连接Broker if (mqtt_client_connect(&client) == 0) { printf("设备通过WebSocket连接MQTT成功\n"); // 上报状态 mqtt_client_publish(&client, "device/aircon/status", "{"temp":26}", 0, 0); } return 0; }
(3)后端服务接入
后端服务(如 Java、Python)可通过 MQTT 客户端库直接连接 WebSocket 端口,实现对设备的管理:
-
Python 示例(使用
paho-mqtt):python
运行
pythonimport paho.mqtt.client as mqtt def on_connect(client, userdata, flags, rc): print(f"连接成功,状态码:{rc}") client.subscribe("device/#") def on_message(client, userdata, msg): print(f"{msg.topic} : {msg.payload.decode()}") # 连接WebSocket端口 client = mqtt.Client(client_id="server-client-789", transport="websockets") client.on_connect = on_connect client.on_message = on_message client.username_pw_set("admin", "public") client.connect("localhost", 8083, 60) client.loop_forever()
三、MQTT+WebSocket 的部署优化(应对大规模设备)
当设备量上升时,需对架构进行优化,避免单点瓶颈:
-
负载均衡:使用 Nginx 或 HAProxy 代理 WebSocket 连接,将请求分发到多个 EMQX 节点:
nginx
ini# Nginx配置示例 http { upstream emqx_ws { server 192.168.1.10:8083; server 192.168.1.11:8083; } server { listen 80; server_name mqtt.example.com; location /mqtt { proxy_pass http://emqx_ws; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; } } } -
集群化部署:将 EMQX 部署为集群,实现连接数的水平扩展,支撑十万 / 百万级设备连接。
-
协议分层:
- 设备端:对低功耗设备,可使用 MQTT over WebSocket 的轻量变体(如 MQTT-SN);
- 服务端:使用 EMQX 的规则引擎,将 MQTT 消息转发到 Kafka/Redis,降低实时转发压力。
四、适用场景与优势总结
| 场景 | 优势体现 |
|---|---|
| 网页端控制智能设备 | 浏览器无需插件,通过 WebSocket 直接与 MQTT Broker 通信,实时性强 |
| 跨网络设备通信 | WebSocket 的 80/443 端口易穿透防火墙,解决传统 MQTT 端口被屏蔽的问题 |
| 混合终端接入 | 设备(TCP/MQTT)、网页(WebSocket/MQTT)、服务端可统一接入同一 Broker |
五、核心总结
MQTT 与 WebSocket 的结合是 "协议复用 + 场景适配" 的典型应用:
- 底层:WebSocket 提供可靠的长连接通道,解决网络穿透和网页端接入问题;
- 上层:MQTT 提供轻量的发布 / 订阅机制,适配物联网设备的低带宽、高并发需求。
通过 EMQX 等成熟的 MQTT Broker,可快速实现二者的结合,且支持从中小规模到百万级设备的平滑扩展,是物联网远程控制的首选方案之一。