Jorgen's blog Jorgen's blog
首页
  • 平台架构
  • 混合式开发记录
  • 推送服务
  • 数据分析
  • 实时调度
  • 架构思想

    • 分布式
  • 编程框架工具

    • 编程语言
    • 框架
    • 开发工具
  • 数据存储与处理

    • 数据库
    • 大数据
  • 消息、缓存与搜索

    • 消息队列
    • 搜索与日志分析
  • 前端与跨端开发

    • 前端技术
    • Android
  • 系统与运维

    • 操作系统
    • 容器化与 DevOps
  • 物联网与安全

    • 通信协议
    • 安全
    • 云平台
newland
  • 关于我
  • 终身学习
  • 关于时间的感悟
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

jorgen

Love it, make mistakes, learn, keep grinding.
首页
  • 平台架构
  • 混合式开发记录
  • 推送服务
  • 数据分析
  • 实时调度
  • 架构思想

    • 分布式
  • 编程框架工具

    • 编程语言
    • 框架
    • 开发工具
  • 数据存储与处理

    • 数据库
    • 大数据
  • 消息、缓存与搜索

    • 消息队列
    • 搜索与日志分析
  • 前端与跨端开发

    • 前端技术
    • Android
  • 系统与运维

    • 操作系统
    • 容器化与 DevOps
  • 物联网与安全

    • 通信协议
    • 安全
    • 云平台
newland
  • 关于我
  • 终身学习
  • 关于时间的感悟
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • MQTT
  • WebSocket:构建实时双向通信的桥梁
  • HTTP/2-加速Web通信的新时代
  • HTTP/2-加速现代Web通信的引擎
  • HTTP/2-加速现代Web通信的新协议
  • HTTP/2与HTTP/3:现代Web协议的性能革命
  • HTTP/HTTPS-Web通信的基石
  • HTTP/HTTPS-万维网通信的基石
  • HTTP/HTTPS - 万维网通信的基础协议
  • HTTP Server-Sent Events - 服务器推送的简单实现方式
  • RESTful API - 现代Web服务的基石
  • SSE-服务器推送事件的轻量级解决方案
  • SSE-构建服务器推送的实时数据流
    • 前言
    • SSE 是什么?
    • SSE 的特点
    • SSE 与 WebSocket 的比较
    • SSE 的应用场景
    • 前端实现 SSE
    • 后端实现 SSE
    • SSE 的高级特性
      • 1. 事件 ID
      • 2. 重连延迟
      • 3. 自定义事件类型
    • SSE 的最佳实践
    • SSE 的局限性
    • 结语
  • Server-Sent Events (SSE) - 轻量级服务器推送技术
  • WebRTC-构建点对点实时通信的利器
  • gRPC-构建高性能RPC服务的利器
  • 实时通信协议对比:WebSocket vs SSE vs gRPC
  • 服务器发送事件(SSE)- 简单高效的实时通信方案
  • 长轮询:在WebSocket时代之前实现实时通信的古老技艺
  • GraphQL-现代API查询语言的革命
  • QUIC协议:HTTP/3的新基石
  • API网关与服务网格-微服务架构的通信基石
  • WebSocket断线重连机制-构建健壮实时通信的关键
  • WebSocket安全:构建安全实时通信的关键考量
  • 消息队列-构建分布式系统的异步通信基石
  • WebSocket子协议-为实时通信定制应用层协议
  • Web通信协议全景图-从HTTP到WebTransport的选择指南
  • WebTransport-HTTP/3时代的下一代实时通信协议
  • 实时通信协议监控与故障排查-保障实时通信系统的稳定性
  • 移动端实时通信协议选择与优化指南
  • 实时通信协议的兼容性与降级策略-构建跨平台的健壮实时应用
  • protocol
Jorgen
2023-10-15
目录

SSE-构建服务器推送的实时数据流

# 前言

在现代 Web 应用中,实时数据更新已经成为许多场景的必备功能。无论是社交媒体的实时通知、股票行情的动态更新,还是在线协作的即时同步,都需要服务器能够主动向客户端推送数据。

在实时通信领域,我们有许多选择:WebSocket、MQTT、SSE(Server-Sent Events)等等。在前面的文章中,我们已经介绍了 WebSocket 和 MQTT 这两种强大的实时通信协议。今天,我将带大家了解另一种简单而有效的实时通信技术——SSE。

提示

SSE(Server-Sent Events)是一种服务器向客户端推送事件的单向通信技术,基于 HTTP 协议,实现简单,适用于服务器向客户端单向数据传输的场景。

# SSE 是什么?

SSE(Server-Sent Events)是一种允许服务器向客户端推送事件的技术。它是 HTML5 标准的一部分,通过 EventSource API 在浏览器中实现。

与 WebSocket 不同,SSE 是单向的,仅支持服务器向客户端发送数据。这种单向特性使得 SSE 在实现上比 WebSocket 更简单,也更易于集成到现有的 HTTP 基础设施中。

SSE 使用普通的 HTTP 协议,数据格式为简单的文本流,每条消息以 "data:" 开头,以双换行符 \n\n 结尾。这种简单的格式使得 SSE 非常易于实现和使用。

# SSE 的特点

SSE 具有以下特点:

  1. 基于 HTTP 协议:SSE 使用普通的 HTTP 协议,不需要额外的端口或协议握手,易于穿越防火墙。
  2. 自动重连:当连接断开时,浏览器会自动尝试重新连接,无需手动处理。
  3. 事件 ID:服务器可以发送事件 ID,客户端可以使用这些 ID 来实现消息的可靠传递。
  4. 自定义事件类型:服务器可以发送不同类型的事件,客户端可以根据事件类型进行不同的处理。
  5. 简单易用:SSE 的 API 非常简单,只需要创建一个 EventSource 对象即可。

# SSE 与 WebSocket 的比较

SSE 和 WebSocket 都是实现实时通信的技术,但它们有一些关键的区别:

特性 SSE WebSocket
协议 基于 HTTP 基于 TCP
数据格式 文本(UTF-8) 文本或二进制
双向通信 仅服务器到客户端 双向
自动重连 支持 不支持(需要手动实现)
事件类型 支持 不支持(需要自定义实现)
跨域 支持 支持
连接数 一个连接可以打开多个 EventSource 一个 WebSocket 连接

从上表可以看出,SSE 和 WebSocket 各有优势。SSE 更简单、更易于实现,并且支持自动重连和事件类型;而 WebSocket 支持双向通信,并且可以传输二进制数据。

# SSE 的应用场景

SSE 适用于以下场景:

  1. 服务器到客户端的单向数据推送:如实时通知、股票行情更新、新闻推送等。
  2. 需要自动重连的场景:SSE 的自动重连机制使得它在网络不稳定的环境下表现更好。
  3. 需要事件类型的场景:SSE 支持不同类型的事件,客户端可以根据事件类型进行不同的处理。
  4. 资源受限的场景:SSE 比 WebSocket 更轻量级,适用于资源受限的环境。

# 前端实现 SSE

在前端,我们可以使用 EventSource API 来接收 SSE 消息。下面是一个简单的示例:

// 创建 EventSource 对象
const eventSource = new EventSource('/events');

// 监听消息事件
eventSource.onmessage = function(event) {
  console.log('收到消息:', event.data);
  // 处理消息数据
};

// 监听特定类型的事件
eventSource.addEventListener('customEvent', function(event) {
  console.log('收到自定义事件:', event.data);
  // 处理自定义事件
});

// 监听错误事件
eventSource.onerror = function(error) {
  console.error('SSE 错误:', error);
  // 处理错误
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

在上面的代码中,我们创建了一个 EventSource 对象,并监听了 onmessage、addEventListener 和 onerror 事件。onmessage 用于接收所有类型的事件,addEventListener 用于接收特定类型的事件,onerror 用于处理连接错误。

# 后端实现 SSE

在后端,我们可以使用任何支持流式输出的技术来实现 SSE。下面是一个使用 Node.js 和 Express 的示例:

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.write('data: 连接成功\n\n');
  
  // 定时发送消息
  const interval = setInterval(() => {
    const message = `data: ${new Date().toISOString()}\n\n`;
    res.write(message);
  }, 1000);
  
  // 客户端断开连接时清理
  req.on('close', () => {
    clearInterval(interval);
    res.end();
  });
});

app.listen(3000, () => {
  console.log('服务器运行在 http://localhost:3000');
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

在上面的代码中,我们设置了正确的响应头,然后使用 res.write() 方法发送 SSE 消息。每条消息以 "data:" 开头,以双换行符 \n\n 结尾。我们还实现了客户端断开连接时的清理逻辑。

# SSE 的高级特性

SSE 还有一些高级特性,可以让我们的实时通信更加健壮和灵活:

# 1. 事件 ID

服务器可以在消息中包含事件 ID,客户端可以使用这些 ID 来实现消息的可靠传递:

// 服务器端
res.write(`id: ${Date.now()}\n`);
res.write(`data: ${message}\n\n`);

// 客户端端
eventSource.onmessage = function(event) {
  const lastEventId = eventSource.lastEventId;
  console.log('最后的事件 ID:', lastEventId);
  console.log('收到消息:', event.data);
};
1
2
3
4
5
6
7
8
9
10

# 2. 重连延迟

服务器可以指定客户端重连的延迟时间:

// 服务器端
res.write(`retry: 5000\n`); // 指定客户端重连延迟为 5 秒
res.write(`data: ${message}\n\n`);
1
2
3

# 3. 自定义事件类型

服务器可以发送不同类型的事件,客户端可以根据事件类型进行不同的处理:

// 服务器端
res.write(`event: update\n`);
res.write(`data: ${updateData}\n\n`);

res.write(`event: notification\n`);
res.write(`data: ${notificationData}\n\n`);

// 客户端端
eventSource.addEventListener('update', function(event) {
  console.log('收到更新事件:', event.data);
  // 处理更新事件
});

eventSource.addEventListener('notification', function(event) {
  console.log('收到通知事件:', event.data);
  // 处理通知事件
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# SSE 的最佳实践

在使用 SSE 时,以下是一些最佳实践:

  1. 正确设置响应头:确保设置了正确的响应头,特别是 Content-Type: text/event-stream 和 Cache-Control: no-cache。
  2. 处理连接断开:实现客户端断开连接时的清理逻辑,避免资源泄漏。
  3. 使用事件 ID:使用事件 ID 来实现消息的可靠传递,特别是在需要确保消息不丢失的场景中。
  4. 合理设置重连延迟:根据应用场景合理设置重连延迟,避免频繁重连导致服务器压力过大。
  5. 错误处理:实现错误处理逻辑,特别是在网络不稳定的环境下。
  6. 性能优化:在高并发场景下,考虑使用连接池或其他技术来优化性能。

# SSE 的局限性

尽管 SSE 有很多优点,但它也有一些局限性:

  1. 仅支持单向通信:SSE 仅支持服务器向客户端发送数据,不支持客户端向服务器发送数据。
  2. 仅支持文本数据:SSE 仅支持文本数据,不支持二进制数据。
  3. 浏览器支持:大多数现代浏览器都支持 SSE,但一些旧浏览器可能不支持。
  4. 连接数限制:浏览器对同一个域名的连接数有限制,过多的 SSE 连接可能会导致性能问题。

# 结语

SSE 是一种简单而有效的实时通信技术,特别适合服务器向客户端单向数据推送的场景。它基于 HTTP 协议,实现简单,支持自动重连和事件类型,易于集成到现有的 Web 应用中。

在选择实时通信技术时,我们应该根据具体的需求和场景来选择。如果只需要服务器向客户端单向推送数据,SSE 是一个很好的选择;如果需要双向通信或传输二进制数据,WebSocket 可能更适合。

希望这篇文章能够帮助你了解 SSE 并在项目中应用它。如果你有任何问题或建议,欢迎在评论区留言讨论!

"简单是复杂的终极形式。" — 达·芬奇

#SSE#Server-Sent Events#实时通信#前端开发
上次更新: 2026/01/28, 10:42:53
SSE-服务器推送事件的轻量级解决方案
Server-Sent Events (SSE) - 轻量级服务器推送技术

← SSE-服务器推送事件的轻量级解决方案 Server-Sent Events (SSE) - 轻量级服务器推送技术→

最近更新
01
LLM
01-30
02
intro
01-30
03
intro
01-30
更多文章>
Theme by Vdoing | Copyright © 2019-2026 Jorgen | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式