一、HTTP长轮询(Long Polling)
1. 工作原理
- 传统轮询(低效):客户端每隔几秒向服务器发一次请求,问“有新数据吗?”,即使服务器没有数据也会立即返回“无”。
- 长轮询(改进):客户端发起请求后,服务器会“挂起”连接,直到有数据或超时才响应。客户端收到响应后立即发起新请求。
2. 实现步骤(以巴法云为例)
-
小程序发起请求:
微信小程序向巴法云服务器发送一个HTTP GET请求,并等待响应。JAVASCRIPT
// 伪代码示例(微信小程序) function longPolling() { wx.request({ url: 'https://bemfa.com/api/msg', data: { topic: 'sensors/temp' }, success: (res) => { console.log('收到数据:', res.data); longPolling(); // 立即发起下一次请求 }, fail: () => { setTimeout(longPolling, 5000); // 5秒后重试 } }); }
-
服务器处理:
- 若巴法云平台在
sensors/temp
主题下有新数据,立即返回给小程序。 - 若无数据,服务器保持连接打开(例如30秒超时),超时后返回“空响应”。
- 若巴法云平台在
3. 特点
- 优点:兼容性好(基于HTTP),适合低频更新场景。
- 缺点:
- 实时性差:数据到达后仍需等待下一次轮询。
- 高延迟:每次请求需重建TCP连接(HTTP/1.1)。
- 服务器资源消耗:大量挂起的连接占用资源。
二、WebSocket
1. 工作原理
- 全双工通信:客户端与服务器通过一次HTTP握手升级为WebSocket连接,之后双方可随时主动发送数据。
- 持久连接:连接建立后一直保持,无需重复握手。
2. 实现步骤(以巴法云为例)
-
小程序建立WebSocket连接:
JAVASCRIPT
// 伪代码(微信小程序) const ws = wx.connectSocket({ url: 'wss://bemfa.com/ws', header: { 'Topic': 'sensors/temp' } }); // 监听服务器消息 ws.onMessage((res) => { console.log('实时数据:', res.data); });
-
服务器处理:
- 巴法云平台将
sensors/temp
主题的数据通过WebSocket连接主动推送给小程序。 - 设备(如ESP8266)发布数据到主题后,平台实时转发至所有订阅的小程序。
- 巴法云平台将
3. 特点
- 优点:
- 实时性强:数据到达即推送。
- 低开销:一个连接处理所有通信,减少网络流量。
- 缺点:
- 协议较复杂:需处理连接状态(如重连、心跳)。
- 旧设备或防火墙可能限制WebSocket。
三、对比表格(长轮询 vs WebSocket)
特性 | HTTP长轮询 | WebSocket |
---|---|---|
实时性 | 延迟较高(依赖轮询间隔) | 实时(毫秒级推送) |
连接开销 | 高(频繁建立/关闭连接) | 低(一个持久连接) |
数据方向 | 半双工(客户端主动拉取) | 全双工(双方主动推送) |
适用场景 | 低频更新(如天气预报) | 高频交互(如聊天、实时监控) |
协议复杂度 | 简单(普通HTTP) | 较复杂(需握手、心跳包) |
兼容性 | 所有设备支持 | 需浏览器/环境支持WebSocket |
四、实例场景分析(巴法云平台)
1. 微信小程序接收数据的方式
-
方式一(HTTP长轮询):
小程序每隔几秒问一次平台:“主题sensors/temp
有新数据吗?” → 平台回答“有”或“无”。
类似场景:刷新邮箱查看新邮件。 -
方式二(WebSocket):
小程序告诉平台:“我订阅了sensors/temp
,有数据直接推给我!” → 平台在数据到达时立即推送。
类似场景:微信消息实时提醒。
2. 巴法云的协议选择
- 为何同时支持两种协议?
- WebSocket:适合需要实时性的场景(如设备控制指令)。
- HTTP长轮询:兼容老旧设备或网络限制严格的环境。
五、简单代码示例
1. HTTP长轮询(Python模拟)
PYTHON
import requests import time def long_polling(): while True: response = requests.get('https://bemfa.com/api/msg', params={'topic': 'sensors/temp'}, timeout=30) if response.status_code == 200: print("收到数据:", response.text) else: print("等待超时,重试...") time.sleep(1) # 立即发起下一次请求 long_polling()
2. WebSocket(JavaScript模拟)
JAVASCRIPT
// 浏览器或Node.js环境 const ws = new WebSocket('wss://bemfa.com/ws'); ws.onopen = () => { ws.send(JSON.stringify({ action: 'subscribe', topic: 'sensors/temp' })); }; ws.onmessage = (event) => { console.log('实时数据:', event.data); };
六、总结
- HTTP长轮询:像“不断打电话问有没有新消息”,适合简单场景。
- WebSocket:像“开通了一条热线,双方随时通话”,适合高实时性需求。
- 巴法云的实现:通过主题屏蔽底层协议差异,开发者只需关注业务逻辑(主题和密钥),平台自动处理协议转换。