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的事件格式
    • SSE的使用方法
      • 服务器端实现
      • Node.js实现
      • 客户端实现
    • SSE的优势
      • 简单易用
      • 自动重连
      • 轻量级
      • 服务器推送
      • 与现有HTTP基础设施兼容
    • SSE的局限性
      • 单向通信
      • 文本数据限制
      • 连接数量限制
      • 浏览器兼容性
    • SSE vs WebSocket
      • 适用场景
      • SSE适合的场景
      • WebSocket适合的场景
    • SSE的最佳实践
      • 服务器端
      • 客户端
      • 跨域处理
    • 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
目录

SSE-服务器推送事件的轻量级解决方案

# 前言

在现代Web应用中,实时通信已经成为许多场景的必备功能,如聊天应用、实时通知、数据更新等。除了WebSocket之外,还有一种轻量级的实时通信技术——SSE(Server-Sent Events,服务器推送事件)。SSE基于HTTP协议,实现简单,适合服务器向客户端的单向数据推送场景。

本文将详细介绍SSE的工作原理、使用方法、优缺点以及与WebSocket的对比,帮助你选择最适合的实时通信方案。

# SSE基础

# 什么是SSE?

SSE(Server-Sent Events)是一种服务器向客户端推送事件的技术,它是HTML5标准的一部分。SSE允许服务器在HTTP连接上向客户端发送事件流,客户端通过JavaScript的EventSource API接收这些事件。

# SSE的工作原理

SSE基于HTTP长连接,工作原理如下:

  1. 客户端请求:客户端向服务器发送一个HTTP请求,请求头中包含Accept: text/event-stream。
  2. 服务器响应:服务器返回一个HTTP响应,状态码为200,内容类型为text/event-stream,并保持连接打开。
  3. 事件流:服务器通过这个连接向客户端发送事件流,每个事件由一个或多个行组成,以双换行符(\n\n)分隔。
  4. 客户端接收:客户端通过EventSource API接收事件,并触发相应的事件处理函数。

# SSE的事件格式

SSE的事件格式非常简单,由以下几个部分组成:

[field]: [value]\n
1

常见的字段包括:

  • event:事件类型,可选。
  • data:事件数据,必须包含。
  • id:事件ID,用于重新连接时确定上次接收的位置。
  • retry:重连时间间隔(毫秒),可选。

示例:

event: message
data: Hello, world!

id: 123
data: This is a message with ID
1
2
3
4
5

# SSE的使用方法

# 服务器端实现

# Node.js实现

const http = require('http');

const server = http.createServer((req, res) => {
  // 只处理SSE请求
  if (req.headers.accept === 'text/event-stream') {
    res.writeHead(200, {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive',
      'Access-Control-Allow-Origin': '*' // 允许跨域
    });

    // 发送事件
    const sendEvent = (data, event = 'message') => {
      res.write(`event: ${event}\n`);
      res.write(`data: ${JSON.stringify(data)}\n\n`);
    };

    // 发送欢迎消息
    sendEvent({ message: 'Connected to SSE server' });

    // 每5秒发送一次时间
    const interval = setInterval(() => {
      sendEvent({ time: new Date().toISOString() });
    }, 5000);

    // 处理连接关闭
    req.on('close', () => {
      clearInterval(interval);
      res.end();
    });
  } else {
    res.writeHead(404);
    res.end('Not found');
  }
});

server.listen(3000, () => {
  console.log('SSE server running on port 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

# 客户端实现

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

// 监听消息事件
eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Received data:', data);
  // 更新UI或其他处理
};

// 监听特定类型的事件
eventSource.addEventListener('message', (event) => {
  const data = JSON.parse(event.data);
  console.log('Custom message:', data);
});

// 处理错误
eventSource.onerror = (error) => {
  console.error('SSE error:', error);
  // 可以在这里实现重连逻辑
};

// 手动关闭连接
// 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

# SSE的优势

# 简单易用

SSE基于HTTP协议,实现简单,不需要像WebSocket那样建立复杂的连接。服务器端只需要返回特定格式的文本流,客户端使用标准的EventSource API即可接收事件。

# 自动重连

SSE内置了自动重连机制,当连接断开时,客户端会自动尝试重新连接。重连间隔可以通过retry字段控制。

# 轻量级

SSE的消息格式简单,头部开销小,适合传输简单的文本数据。相比于WebSocket的二进制协议,SSE更容易调试和监控。

# 服务器推送

SSE专门为服务器向客户端的单向数据推送设计,非常适合服务器主动通知客户端的场景,如实时更新、通知等。

# 与现有HTTP基础设施兼容

SSE使用标准的HTTP端口(80/443),可以轻松通过现有的HTTP代理、负载均衡器和防火墙,不需要额外的网络配置。

# SSE的局限性

# 单向通信

SSE只支持服务器向客户端的单向通信,客户端无法通过SSE向服务器发送数据。如果需要双向通信,必须使用其他方法(如额外的HTTP请求)。

# 文本数据限制

SSE主要设计用于传输文本数据,虽然可以通过Base64编码传输二进制数据,但这会增加数据大小和处理复杂度。

# 连接数量限制

由于SSE基于HTTP长连接,每个客户端都会占用一个服务器连接。对于大量客户端的场景,这可能会成为服务器的负担。

# 浏览器兼容性

虽然大多数现代浏览器都支持SSE,但IE浏览器不支持SSE。对于需要支持IE的项目,需要提供备选方案。

# SSE vs WebSocket

特性 SSE WebSocket
协议 HTTP 自定义协议
数据格式 文本 文本和二进制
通信方向 单向(服务器→客户端) 双向
连接管理 自动重连 手动管理
头部开销 小 大
复杂度 低 高
浏览器兼容性 现代浏览器 所有现代浏览器
服务器支持 简单 较复杂

# 适用场景

# SSE适合的场景

  • 服务器向客户端的单向数据推送,如实时通知、更新等。
  • 需要简单、轻量级解决方案的场景。
  • 对实时性要求不是特别高的场景。
  • 已经有HTTP基础设施,不想引入新协议的场景。

# WebSocket适合的场景

  • 需要双向通信的场景,如聊天应用、多人游戏等。
  • 需要低延迟、高频率数据交换的场景。
  • 需要传输二进制数据的场景,如文件传输、视频流等。
  • 对实时性要求高的场景。

# SSE的最佳实践

# 服务器端

  1. 设置正确的响应头:确保设置正确的Content-Type和Cache-Control等响应头。
  2. 处理连接关闭:监听连接关闭事件,清理资源。
  3. 实现心跳机制:定期发送心跳消息,保持连接活跃。
  4. 错误处理:实现适当的错误处理逻辑,如重连策略。
  5. 限制数据量:避免发送过大的数据块,影响性能。

# 客户端

  1. 错误处理:实现完善的错误处理和重连逻辑。
  2. 事件过滤:根据事件类型进行过滤,只处理需要的事件。
  3. 资源清理:在不需要时关闭连接,释放资源。
  4. 降级方案:对于不支持SSE的浏览器,提供备选方案(如轮询)。

# 跨域处理

SSE请求会受到浏览器的同源策略限制,如果需要跨域使用SSE,服务器需要设置适当的CORS头:

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
1
2

# SSE的实际应用案例

# 实时通知系统

// 服务器端
app.get('/notifications', (req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });

  // 模拟通知
  const notifications = [
    { id: 1, message: 'You have a new message', time: new Date() },
    { id: 2, message: 'Meeting in 10 minutes', time: new Date() },
    { id: 3, message: 'Your order has been shipped', time: new Date() }
  ];

  notifications.forEach(notification => {
    res.write(`data: ${JSON.stringify(notification)}\n\n`);
  });

  // 模拟新通知
  setTimeout(() => {
    res.write(`data: ${JSON.stringify({
      id: 4,
      message: 'New notification received',
      time: new Date()
    })}\n\n`);
  }, 5000);
});
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
// 客户端
const eventSource = new EventSource('/notifications');

eventSource.onmessage = (event) => {
  const notification = JSON.parse(event.data);
  showNotification(notification);
};
1
2
3
4
5
6
7

# 结语

SSE作为一种轻量级的服务器推送技术,为Web应用提供了一种简单、高效的实时通信解决方案。虽然它只支持单向通信,但在服务器向客户端推送数据的场景中,SSE比WebSocket更简单、更高效。

通过本文的介绍,我们了解了SSE的工作原理、使用方法、优缺点以及与WebSocket的对比。在实际应用中,我们应该根据具体需求选择最适合的实时通信方案。对于简单的服务器推送场景,SSE是一个理想的选择;而对于需要双向通信、低延迟或二进制数据传输的场景,WebSocket可能更为合适。

随着Web技术的不断发展,实时通信已经成为现代Web应用不可或缺的一部分。掌握SSE和WebSocket等实时通信技术,将帮助我们构建更加动态、交互性更强的Web应用。

"SSE虽小,却蕴含着实时通信的无限可能。选择合适的工具,才能事半功倍。"

#SSE#Server-Sent Events#服务器推送#实时通信#轻量级
上次更新: 2026/01/28, 10:42:53
RESTful API - 现代Web服务的基石
SSE-构建服务器推送的实时数据流

← RESTful API - 现代Web服务的基石 SSE-构建服务器推送的实时数据流→

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