MQTT vs WebSocket:一文看懂关键差异与实战选型
🚀 MQTT vs WebSocket:一文看懂关键差异与实战选型(附代码)
在构建实时应用(如即时通讯、物联网监控、股票行情推送)时,我们经常会面临一个经典的技术选型问题:到底是用 MQTT 还是 WebSocket?
很多开发者容易混淆这两者,甚至觉得它们是竞争关系。其实,它们更像是“高速公路”和“快递车队”的关系。今天我们就来彻底搞懂它们的区别,并附上简单的代码 Demo,帮你做出最正确的架构决策。
💡 核心概念:不仅仅是二选一
首先,我们需要纠正一个常见的误区:MQTT 和 WebSocket 并不完全是在同一个层面上的协议。
- WebSocket 是一种传输协议。它就像一条双向车道,建立连接后,客户端和服务端可以随意互相喊话。但它不管你们聊的内容是什么格式,也不管消息有没有送达,它只负责“传”。
- MQTT 是一种应用层消息协议。它定义了一套严谨的“快递规则”(发布/订阅模式)。它规定了消息怎么打包、丢了怎么办(QoS)、谁该收这份快递(Topic)。
有趣的事实:MQTT 可以运行在 TCP 之上,也可以运行在 WebSocket 之上(即 MQTT over WebSocket)。
⚔️ 关键差异大比拼
为了让你一目了然,我做了一个核心特性对比表:
| 维度 | WebSocket | MQTT |
|---|---|---|
| 通信模型 | 点对点 (Client-Server) | 发布/订阅 (Pub/Sub) |
| 消息路由 | 需业务层自己写逻辑处理 | 基于 Topic (主题) 自动路由 |
| 可靠性 | 依赖 TCP,无应用层确认机制 | 提供 QoS 0/1/2 三级服务质量 |
| 离线消息 | 需自行实现存储与重推 | 原生支持保留消息与会会话恢复 |
| 带宽消耗 | 较低 (头部较小) | 极低 (固定头部最小仅 2 字节) |
| 浏览器支持 | 原生支持 (new WebSocket()) |
需引入库 (如 mqtt.js) |
| 适用场景 | Web聊天、在线协作、自定义协议 | IoT设备、大规模消息分发、弱网环境 |
🧐 什么时候选哪个?
-
选择 WebSocket,如果…
- 你的核心场景是 Web 端即时通讯(如网页版微信),且不需要复杂的群组管理。
- 你需要极高的定制自由度,想自己定义二进制协议格式。
- 交互主要是“请求-响应”模式的变种,或者是一对一的私密通话。
-
选择 MQTT,如果…
- 你在做 IoT(物联网),设备资源受限,网络不稳定(需要 QoS 保活)。
- 你需要实现复杂的 一对多 分发(例如:一个传感器数据要同时推送到手机App、Web大屏和数据库)。
- 你希望后端服务解耦,不想自己写复杂的消息路由和广播逻辑。
💻 前端实战:JS 版本接入指南
在浏览器环境中,情况稍微有点特殊:
- WebSocket:浏览器原生支持,无需安装任何库,直接用
new WebSocket()。 - MQTT:浏览器不支持原生的 TCP 连接,因此我们需要使用 MQTT over WebSocket。这通常需要引入第三方库,最流行的是
mqtt.js。
1. WebSocket 前端实现 (原生 JS)
这是最纯粹的 WebSocket 写法,适用于简单的聊天室或实时通知。
<!DOCTYPE html>
<html>
<head><title>WebSocket Demo</title></head>
<body>
<h2>原生 WebSocket 客户端</h2>
<div id="status">状态: 未连接</div>
<input type="text" id="msgInput" placeholder="输入消息" />
<button onclick="sendMsg()">发送</button>
<ul id="log"></ul>
<script>
// 1. 建立连接 (注意:生产环境通常用 wss://)
const ws = new WebSocket('ws://localhost:9001');
// 2. 连接成功
ws.onopen = () => {
document.getElementById('status').innerText = '状态: 已连接 ✅';
addLog('连接到服务器成功');
};
// 3. 接收消息
ws.onmessage = (event) => {
addLog('收到: ' + event.data);
};
// 4. 连接关闭
ws.onclose = () => {
document.getElementById('status').innerText = '状态: 已断开 ❌';
addLog('连接已关闭');
};
// 5. 发送消息函数
function sendMsg() {
const input = document.getElementById('msgInput');
if(ws.readyState === WebSocket.OPEN) {
ws.send(input.value);
addLog('我说: ' + input.value);
input.value = '';
} else {
alert('连接未开启');
}
}
function addLog(text) {
const li = document.createElement('li');
li.innerText = text;
document.getElementById('log').appendChild(li);
}
</script>
</body>
</html>
2. MQTT 前端实现 (使用 mqtt.js)
对于 MQTT,我们需要通过 CDN 引入库,并连接到支持 WebSocket 协议的 MQTT Broker(如 EMQX, Mosquitto 等)。
前置准备:
你需要一个开启了 WebSocket 端口的 MQTT Broker。如果你没有,可以使用公共测试服务器 ws://broker.hivemq.com:8000/mqtt 进行测试。
<!DOCTYPE html>
<html>
<head><title>MQTT.js Demo</title></head>
<body>
<h2>MQTT.js 客户端</h2>
<div id="status">状态: 离线</div>
<div>
<label>主题(Topic): </label>
<input type="text" id="topic" value="test/topic/1" />
</div>
<br>
<input type="text" id="msgInput" placeholder="输入消息" />
<button onclick="publish()">发布消息</button>
<button onclick="subscribe()">订阅主题</button>
<ul id="log"></ul>
<!-- 引入 mqtt.js 库 -->
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
<script>
// 1. 连接配置
// 注意:浏览器只能用 ws:// 或 wss://,不能用 tcp://
const options = {
clientId: 'web_client_' + Math.random().toString(16).substr(2, 8),
clean: true, // 不保留会话
connectTimeout: 4000,
reconnectPeriod: 1000, // 重连间隔
};
// 2. 建立连接 (这里使用的是 HiveMQ 的公共测试服务器)
const client = mqtt.connect('ws://broker.hivemq.com:8000/mqtt', options);
// 3. 连接成功回调
client.on('connect', () => {
document.getElementById('status').innerText = '状态: 已连接到 Broker ✅';
addLog('MQTT 连接成功!');
});
// 4. 接收消息回调
client.on('message', (topic, message) => {
addLog(`收到 [${topic}]: ${message.toString()}`);
});
// 5. 订阅功能
function subscribe() {
const topic = document.getElementById('topic').value;
client.subscribe(topic, (err) => {
if (!err) {
addLog(`订阅成功: ${topic}`);
} else {
addLog('订阅失败');
}
});
}
// 6. 发布功能
function publish() {
const topic = document.getElementById('topic').value;
const msg = document.getElementById('msgInput').value;
client.publish(topic, msg, { qos: 1 }, (err) => {
if(!err) {
addLog(`发布成功 [${topic}]: ${msg}`);
document.getElementById('msgInput').value = '';
}
});
}
function addLog(text) {
const li = document.createElement('li');
li.innerText = text;
document.getElementById('log').appendChild(li);
}
</script>
</body>
</html>
📝 代码对比小结
| 特性 | WebSocket (原生) | MQTT (mqtt.js) |
|---|---|---|
| 依赖库 | 无 (浏览器自带) | 需引入 mqtt.min.js |
| 连接地址 | ws://host:port/path |
ws://host:port/path (必须是 WS 协议) |
| 核心逻辑 | send(), onmessage |
publish(), subscribe(), on('message') |
| 数据理解 | 只负责传字符串/二进制 | 理解 Topic 和 QoS |
💻 实战 Demo:手把手教你用
为了演示,我们使用 Python 作为服务端(Broker/Server),分别展示两种协议的实现方式。
前置准备:
# 安装 MQTT 库
pip install paho-mqtt
# 安装 WebSocket 库
pip install websocket-server
场景一:使用 MQTT 实现“发布/订阅”
假设我们要做一个温度监控系统,设备发布温度,多个客户端订阅接收。
服务端(模拟 Broker 逻辑,实际生产推荐用 EMQX 或 Mosquitto):
注:这里主要演示客户端如何交互,通常 MQTT 直接连接现成的 Broker。
发布者 (Publisher) 代码:
import paho.mqtt.client as mqtt
import time
def on_connect(client, userdata, flags, rc):
print(f"已连接到 Broker,结果: {rc}")
client = mqtt.Client()
client.on_connect = on_connect
# 连接本地 Broker (需提前安装 mosquitto 或使用测试服务器)
client.connect("broker.hivemq.com", 1883, 60)
while True:
# 向 'home/livingroom/temp' 主题发布消息
client.publish("home/livingroom/temp", "26.5°C")
print("发布了温度数据: 26.5°C")
time.sleep(3)
订阅者 (Subscriber) 代码:
import paho.mqtt.client as mqtt
def on_message(client, userdata, msg):
print(f"收到消息 [主题: {msg.topic}]: {str(msg.payload)}")
client = mqtt.Client()
client.on_message = on_message
client.connect("broker.hivemq.com", 1883, 60)
# 订阅特定主题
client.subscribe("home/livingroom/temp")
client.loop_forever()
场景二:使用 WebSocket 实现“点对点”聊天
假设我们要做一个简单的回声服务器(Echo Server)。
服务端代码:
from websocket_server import WebsocketServer
def new_client(client, server):
print(f"新用户连接: {client['id']}")
server.send_message(client, "欢迎连接到 WebSocket 服务器!")
def message_received(client, server, message):
print(f"收到消息: {message}")
# 广播给所有用户
server.send_message_to_all(f"用户{client['id']}说: {message}")
server = WebsocketServer(port=9001)
server.set_fn_new_client(new_client)
server.set_fn_message_received(message_received)
print("WebSocket 服务器启动中...")
server.run_forever()
客户端代码 (Python):
import websocket
def on_message(ws, message):
print(f"收到: {message}")
def on_open(ws):
print("连接已建立,发送消息...")
ws.send("你好,WebSocket!")
ws = websocket.WebSocket()
ws.connect("ws://localhost:9001")
on_open(ws)
# 保持接收
while True:
msg = ws.recv()
on_message(ws, msg)
🏆 总结与建议
在实际的企业级开发中,现在的趋势往往是 “混合双打”:
- 设备端 -> 云端:使用 MQTT,保证弱网下的可靠传输和设备状态管理。
- 云端 -> Web/App:使用 MQTT over WebSocket 或者直接封装一层 WebSocket。
如果你的项目刚开始,规模不大,且主要在浏览器上跑,直接用 WebSocket 最快;如果你面对的是成千上万的传感器或复杂的推送需求,请务必拥抱 MQTT。
希望这篇文章能帮你在技术选型时少走弯路!如果觉得有用,欢迎点赞收藏关注!👋
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)