长连接有哪几种实现方式

长连接(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());
});

总结

常见的长连接实现方式有:

  1. WebSocket:最常见的全双工实时通信协议,适用于高频率、低延迟的实时应用。
  2. Server-Sent Events (SSE):基于 HTTP 协议的单向数据推送,适用于需要实时更新的应用。
  3. Long Polling:模拟长连接的方式,适用于老旧浏览器或不支持 WebSocket 和 SSE 的环境。
  4. HTTP/2 Server Push:通过 HTTP/2 推送数据,适用于优化传输效率和实时更新的场景。
  5. MQTT:适用于物联网和实时消息推送的轻量级协议。

每种方式有不同的使用场景,选择合适的实现方式可以帮助提高应用的实时性和性能。

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1

我还是最喜欢ws :kissing_heart:

2个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!