长连接有哪几种实现方式
长连接(Long Polling)是指客户端与服务器之间建立的长期保持连接,用于实现实时数据的交换,通常用于 Web 应用中实现实时通知、消息推送等功能。长连接的实现方式有几种,以下是常见的几种实现方式:
1. WebSocket
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。它是 HTML5 中新增的协议,允许客户端和服务器之间进行持续的、低延迟的双向通信,非常适合需要实时互动的应用。
特点:
- 双向通信:客户端和服务器都可以主动发送消息。
- 持久连接:一旦连接建立,通信会一直保持,直到任意一方主动关闭连接。
- 低延迟:适用于实时、互动性强的应用,如在线游戏、实时聊天等。
示例:
// 客户端
const socket = new WebSocket('ws://example.com/socket');
socket.onopen = () => console.log('WebSocket is open now.');
socket.onmessage = (event) => console.log('Received message:', event.data);
socket.send('Hello Server!');
// 服务器端 (Node.js 示例)
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => {
ws.on('message', (message) => {
console.log('Received:', message);
});
ws.send('Hello Client!');
});
2. Server-Sent Events (SSE)
Server-Sent Events(SSE)是一种通过 HTTP 协议由服务器向客户端单向推送实时事件的技术。客户端通过 EventSource
API 监听事件,服务器持续地推送数据到客户端。SSE 是建立在 HTTP 协议之上的,所以它比 WebSocket 更简单,但它只能进行单向通信,不能由客户端主动发送消息。
特点:
- 单向通信:服务器向客户端推送数据,客户端无法向服务器发送数据(除非通过其他方式)。
- 持久连接:连接在客户端与服务器之间保持打开状态,直到客户端关闭连接。
- 适用于实时更新的应用,如股票价格、新闻推送等。
示例:
// 客户端
const eventSource = new EventSource('/events');
eventSource.onmessage = (event) => console.log('New message from server:', event.data);
// 服务器端 (Node.js 示例)
const express = require('express');
const app = express();
app.get('/events', (req, res) => {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.flushHeaders();
setInterval(() => {
res.write('data: Hello from server\n\n');
}, 1000);
});
app.listen(3000, () => console.log('Server running on port 3000'));
3. Long Polling
Long Polling 是一种通过模拟长连接的方式来实现实时通信的技术。在这种方式中,客户端向服务器发送一个请求,服务器不立即响应,而是等待直到有新数据或超时为止。当数据准备好时,服务器会返回响应给客户端,客户端收到响应后会立即重新发送请求。这样客户端与服务器之间就保持了一个持续的通信链路。
特点:
- 单向通信:客户端发送请求,服务器返回响应。
- 持久连接:虽然每个请求响应都会断开连接,但客户端会立即发起新的请求,模拟了一个持续连接。
- 延迟较高:相比 WebSocket 和 SSE,Long Polling 需要每次请求响应后重建连接,存在一定延迟,且会占用更多的资源。
示例:
// 客户端
function longPoll() {
fetch('/long-poll')
.then((response) => response.json())
.then((data) => {
console.log('Received:', data);
longPoll(); // 重新发送请求
})
.catch(() => {
setTimeout(longPoll, 1000); // 如果发生错误,稍后重试
});
}
longPoll();
// 服务器端 (Node.js 示例)
const express = require('express');
const app = express();
app.get('/long-poll', (req, res) => {
setTimeout(() => {
res.json({ message: 'Hello from server!' });
}, 5000); // 模拟延迟
});
app.listen(3000, () => console.log('Server running on port 3000'));
4. HTTP/2 Server Push
HTTP/2 引入了一个名为 Server Push 的功能,允许服务器主动推送资源给客户端。虽然 HTTP/2 Push 更常用于发送静态资源(如 CSS、JS 文件),但它也可以用于实现一些简单的推送机制。
特点:
- 基于 HTTP/2 协议,可以利用 HTTP/2 的多路复用特性,提高通信效率。
- 服务端可以主动推送资源到客户端,客户端无需等待请求。
- 实现相对复杂,适用于优化 HTTP 请求和实时数据传输。
示例:
// 服务器端 (Node.js 示例)
const http2 = require('http2');
const server = http2.createServer();
server.on('stream', (stream, headers) => {
stream.respond({
'content-type': 'text/html',
':status': 200,
});
stream.write('<h1>Hello, HTTP/2!</h1>');
stream.pushStream({ ':path': '/styles.css' }, (pushStream) => {
pushStream.respond({ 'content-type': 'text/css' });
pushStream.end('body { background: blue; }');
});
stream.end();
});
server.listen(3000);
5. MQTT
MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息传输协议,通常用于物联网(IoT)场景中。在某些实时应用中,MQTT 也被用于实现长连接和实时数据推送。
特点:
- 发布/订阅模式:客户端订阅某个主题,服务器发布消息到该主题,所有订阅该主题的客户端都会接收到消息。
- 适用于低带宽、高延迟的网络环境,广泛应用于 IoT 和实时通信应用。
示例:
// 客户端 (JavaScript 示例)
const mqtt = require('mqtt');
const client = mqtt.connect('mqtt://broker.hivemq.com');
client.on('connect', () => {
console.log('Connected to MQTT broker');
client.subscribe('test/topic');
});
client.on('message', (topic, message) => {
console.log('Received message:', topic, message.toString());
});
总结
常见的长连接实现方式有:
- WebSocket:最常见的全双工实时通信协议,适用于高频率、低延迟的实时应用。
- Server-Sent Events (SSE):基于 HTTP 协议的单向数据推送,适用于需要实时更新的应用。
- Long Polling:模拟长连接的方式,适用于老旧浏览器或不支持 WebSocket 和 SSE 的环境。
- HTTP/2 Server Push:通过 HTTP/2 推送数据,适用于优化传输效率和实时更新的场景。
- MQTT:适用于物联网和实时消息推送的轻量级协议。
每种方式有不同的使用场景,选择合适的实现方式可以帮助提高应用的实时性和性能。
本作品采用《CC 协议》,转载必须注明作者和本文链接
我还是最喜欢ws :kissing_heart: