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 - 服务器推送的简单实现方式
    • SSE 的数据格式
      • 基本字段
      • 示例
    • SSE 的进阶使用
      • 自定义事件类型
      • 事件 ID 和重连
    • SSE 的应用场景
    • SSE 的浏览器兼容性
    • 结语
  • RESTful API - 现代Web服务的基石
  • 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-11-15
目录

HTTP Server-Sent Events - 服务器推送的简单实现方式


## 前言

在现代 Web 应用中,实时通信已成为许多功能的基础需求。无论是社交媒体的实时更新、聊天应用的消息推送,还是金融数据的实时展示,都需要服务器能够主动向客户端推送数据。

我们已经了解了 WebSocket 和 MQTT 这两种强大的实时通信协议,但它们在某些场景下可能显得过于复杂。今天,我将介绍一种更轻量级的服务器到客户端的实时通信技术——Server-Sent Events (SSE)。

::: tip
Server-Sent Events (SSE) 是一种允许服务器向客户端推送事件的 Web 技术。它是 HTML5 标准的一部分,基于 HTTP 协议实现,使用简单且兼容性好。
:::

## 什么是 Server-Sent Events?

Server-Sent Events (SSE) 是一种服务器向客户端推送数据的技术。与传统的客户端请求-服务器响应模式不同,SSE 允许服务器在数据更新时主动向客户端发送消息,而不需要客户端先发起请求。

SSE 基于 HTTP 协议实现,使用 `text/event-stream` MIME 类型。服务器通过保持一个长连接,定期发送数据事件,客户端则通过 `EventSource` API 接收这些事件。

## SSE 的特点

与 WebSocket 和 MQTT 相比,SSE 有以下特点:

### 优点

1. **简单易用**:SSE 基于 HTTP 协议,实现相对简单,不需要复杂的握手和协议协商。
2. **自动重连**:SSE 客户端内置了自动重连机制,在网络中断后会自动尝试重新连接。
3. **轻量级**:SSE 使用简单的文本格式传输数据,开销小,适合简单的服务器推送场景。
4. **标准支持**:SSE 是 HTML5 标准的一部分,所有现代浏览器都原生支持。

### 缺点

1. **单向通信**:SSE 只支持服务器到客户端的单向通信,客户端无法通过同一个连接向服务器发送数据。
2. **不支持二进制数据**:SSE 只支持文本数据,无法直接传输二进制数据(如图片、视频等)。
3. **并发连接限制**:浏览器对同一服务器的并发连接数有限制(通常为6个),这可能会影响需要多个 SSE 连接的应用。

## SSE 与 WebSocket 的比较

| 特性 | SSE | WebSocket |
|------|-----|----------|
| 协议 | 基于 HTTP | 独立的协议 |
| 数据格式 | 纯文本 | 文本和二进制 |
| 通信方向 | 单向(服务器→客户端) | 双向 |
| 自动重连 | 内置支持 | 需要手动实现 |
| 复杂度 | 简单 | 复杂 |
| 适用场景 | 简单的服务器推送 | 需要双向通信的复杂应用 |

## SSE 的基本使用

### 客户端实现

在客户端,我们可以使用 `EventSource` API 来接收 SSE 事件:

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

// 监听消息事件
eventSource.onmessage = function(event) {
  const data = JSON.parse(event.data);
  console.log('收到消息:', data);
};

// 监听特定类型的事件
eventSource.addEventListener('custom-event', function(event) {
  const data = JSON.parse(event.data);
  console.log('收到自定义事件:', data);
});

// 监听错误事件
eventSource.onerror = function(error) {
  console.error('SSE 错误:', error);
  
  // 如果连接断开,EventSource 会自动尝试重连
  // 我们也可以手动关闭连接
  // eventSource.close();
};
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

# 服务器实现

在服务器端,我们需要设置正确的 HTTP 头并持续发送事件数据。以下是一个 Node.js 的示例:

const http = require('http');

const server = http.createServer((req, res) => {
  // 只处理 /api/events 路径的请求
  if (req.url === '/api/events') {
    // 设置 SSE 所需的 HTTP 头
    res.writeHead(200, {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive',
      'Access-Control-Allow-Origin': '*' // 允许跨域
    });
    
    // 发送一条初始消息
    res.write('data: {"type": "connection", "message": "连接成功"}\n\n');
    
    // 模拟定期发送数据
    const intervalId = setInterval(() => {
      const data = {
        type: 'update',
        message: `当前时间: ${new Date().toLocaleString()}`,
        value: Math.random()
      };
      res.write(`data: ${JSON.stringify(data)}\n\n`);
    }, 1000);
    
    // 当客户端断开连接时,清除定时器
    req.on('close', () => {
      clearInterval(intervalId);
      console.log('客户端断开连接');
    });
  } else {
    res.writeHead(404);
    res.end('Not Found');
  }
});

server.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
29
30
31
32
33
34
35
36
37
38
39
40

# SSE 的数据格式

SSE 使用简单的文本格式传输数据。每条消息由一个或多个字段组成,字段之间用换行符分隔,消息之间用双换行符(\n\n)分隔。

# 基本字段

  1. data:消息的内容。可以有多行 data 字段,它们会被视为同一个消息的一部分。
  2. event:事件的类型。客户端可以通过 addEventListener 监听特定类型的事件。
  3. id:事件的唯一标识符。用于断线重连时从上次的位置继续接收数据。
  4. retry:客户端重连的延迟时间(毫秒)。

# 示例

data: {"type": "message", "content": "这是一条消息"}

event: notification
data: {"type": "notification", "content": "这是一条通知"}
id: 12345

retry: 5000
data: {"type": "heartbeat", "content": "心跳"}
1
2
3
4
5
6
7
8

# SSE 的进阶使用

# 自定义事件类型

除了默认的 message 事件外,我们还可以发送自定义事件类型:

// 服务器端
res.write('event: customEvent\ndata: {"message": "这是一个自定义事件"}\n\n');

// 客户端
eventSource.addEventListener('customEvent', function(event) {
  console.log('收到自定义事件:', event.data);
});
1
2
3
4
5
6
7

# 事件 ID 和重连

SSE 支持事件 ID,用于断线重连时从上次的位置继续接收数据:

// 服务器端
let eventId = 0;
setInterval(() => {
  eventId++;
  res.write(`id: ${eventId}\ndata: {"message": "消息 #${eventId}"}\n\n`);
}, 1000);

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

# SSE 的应用场景

SSE 适用于以下场景:

  1. 实时通知:如社交媒体更新、新闻推送、邮件通知等。
  2. 实时数据展示:如股票价格、体育赛事比分、天气预报等。
  3. 日志监控:实时显示服务器日志或应用程序日志。
  4. 聊天应用:简单的服务器到客户端的消息推送(如果需要双向通信,可以考虑结合 WebSocket)。

# SSE 的浏览器兼容性

SSE 得到了所有现代浏览器的支持:

  • Chrome
  • Firefox
  • Safari
  • Edge

需要注意的是,Internet Explorer 不支持 SSE。

# 结语

Server-Sent Events 是一种简单而有效的服务器到客户端的实时通信技术。它基于 HTTP 协议,实现简单,兼容性好,特别适合不需要双向通信的实时推送场景。

与 WebSocket 相比,SSE 更轻量级,实现更简单;与 MQTT 相比,SSE 更适合 Web 应用,不需要额外的客户端库。

在选择实时通信技术时,应根据具体需求和技术栈来决定:

  • 如果只需要服务器到客户端的单向通信,且希望实现简单,SSE 是一个不错的选择。
  • 如果需要双向通信,或者需要支持移动应用和物联网设备,WebSocket 可能更合适。
  • 如果是在物联网环境中,需要低带宽、低功耗的通信,MQTT 可能是更好的选择。

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

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

#HTTP#SSE#实时通信#服务器推送
上次更新: 2026/01/28, 14:21:05
HTTP/HTTPS - 万维网通信的基础协议
RESTful API - 现代Web服务的基石

← HTTP/HTTPS - 万维网通信的基础协议 RESTful API - 现代Web服务的基石→

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