在web开发中,实时通讯指的是客户端和服务器之间能够持续保持数据交互,服务器可以主动将最新数据推送到客户端,不需要客户端反复发起请求。HTML原生的基础能力并不支持这种双向实时交互,需要结合HTML5新增的特性和传统方案的优化来实现。

HTML原生能力的缺失
HTML最初的设计是基于请求-响应模式,客户端通过<a>标签跳转、<form>表单提交或者XMLHttpRequest发起请求,服务器收到请求后返回对应数据,整个流程是客户端主动发起,服务器无法主动推送数据。原生的HTML能力存在以下不足:
- 不支持服务器主动推送,只能靠客户端轮询获取新数据,浪费带宽和资源
- 没有原生的双向通信通道,每次交互都需要重新建立连接或者复用短连接,延迟较高
- 无法保持长时间的稳定连接,传统的HTTP连接在完成响应后就会断开,不适合实时场景
HTML5提供的实时通讯方案及原理
1. 长轮询(Long Polling)
长轮询是对传统轮询的优化,属于HTML5之前就存在但结合HTML5能力更优的方案。原理是客户端发起请求后,服务器不会立即返回响应,而是等到有数据更新或者连接超时才返回,客户端收到响应后马上再次发起请求,保持连接的持续性。
实现示例:
// 客户端长轮询实现
function longPolling() {
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/poll', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
const data = JSON.parse(xhr.responseText);
console.log('收到新数据:', data);
// 收到响应后立即再次发起请求
longPolling();
}
};
xhr.send();
}
longPolling();
2. Server-Sent Events(SSE)
SSE是HTML5新增的服务器推送技术,基于HTTP协议,允许服务器向客户端单向推送数据流。它的原理是客户端通过<EventSource>接口和服务器建立连接,服务器返回的内容类型是text/event-stream,并且保持连接不中断,持续向客户端发送格式化的消息。
服务器端的简单实现示例:
const http = require('http');
http.createServer((req, res) => {
if (req.url === '/sse') {
// 设置响应头为事件流类型
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
// 定时向客户端推送数据
const timer = setInterval(() => {
const data = `data: ${JSON.stringify({ time: new Date().toLocaleTimeString() })}nn`;
res.write(data);
}, 1000);
// 连接关闭时清除定时器
req.on('close', () => {
clearInterval(timer);
});
}
}).listen(3000);
客户端使用<EventSource>接收数据的示例:
const eventSource = new EventSource('/sse');
eventSource.onmessage = function(e) {
const data = JSON.parse(e.data);
console.log('SSE收到推送:', data);
};
eventSource.onerror = function() {
console.log('SSE连接出错');
};
3. WebSocket
WebSocket是HTML5提供的全双工通信协议,它和HTTP协议不同,通过一次HTTP握手升级为WebSocket连接后,客户端和服务器可以双向主动发送数据,连接会一直保持直到主动关闭。这是HTML5中最适合实时双向通讯的方案。
WebSocket握手过程示例:
// 客户端握手请求 GET /ws HTTP/1.1 Host: localhost:3000 Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13 // 服务器握手响应 HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
客户端WebSocket实现示例:
const ws = new WebSocket('ws://localhost:3000/ws');
// 连接建立成功回调
ws.onopen = function() {
console.log('WebSocket连接已建立');
// 向服务器发送数据
ws.send(JSON.stringify({ type: 'hello', content: '客户端发送的消息' }));
};
// 收到服务器消息回调
ws.onmessage = function(e) {
const data = JSON.parse(e.data);
console.log('收到服务器消息:', data);
};
// 连接关闭回调
ws.onclose = function() {
console.log('WebSocket连接已关闭');
};
不同方案对比
三种常见的实时通讯方案的特点对比如下:
| 方案 | 通信方向 | 协议基础 | 适用场景 |
|---|---|---|---|
| 长轮询 | 单向(服务器被动响应) | HTTP | 实时性要求不高的简单推送场景 |
| SSE | 单向(服务器主动推送) | HTTP | 股票行情、新闻推送等服务器到客户端的单向场景 |
| WebSocket | 双向全双工 | 独立的WebSocket协议 | 即时聊天、多人协作、实时游戏等双向交互场景 |
总结
HTML原生不具备实时通讯能力,核心原因是其基于请求-响应的单向交互模式,无法支持服务器主动推送和长时间稳定连接。HTML5通过优化传统长轮询、新增SSE和WebSocket能力,补全了web端的实时通讯短板。开发者可以根据业务场景选择合适的方案,单向推送优先选SSE,双向交互优先选WebSocket,兼容性要求高的场景可以用长轮询作为降级方案。
HTML5实时通讯WebSocketServer_Sent_Events长轮询修改时间:2026-07-15 22:45:38