当前位置: 首页 > news >正文

SSE协议

Server-Sent Events(SSE)是一种允许服务器主动向客户端推送数据的技术,它基于HTTP协议,通过创建一个持久的连接来实现。这种技术非常适合用于需要服务器实时更新数据的应用场景,如股票价格更新、新闻订阅、实时通知等。

工作原理

SSE 通过 HTTP 协议实现,客户端通过 JavaScript 的 EventSource 对象与服务器建立连接。一旦连接建立,服务器就可以在任何时候向客户端推送信息。数据以文本流的形式发送,每个事件消息以一个空行分隔,并且可以包含以下字段:

  • data:必须的,包含事件的数据。
  • event:可选的,表示事件的类型。
  • id:可选的,表示事件的唯一标识符。
  • retry:可选的,指定客户端在连接失败时重连的间隔时间。

使用场景

SSE 适用于以下场景:

  • 实时通知和警报:如实时股票行情、新闻推送等。
  • 聊天应用:虽然 WebSocket 更适用于双向通信,但在某些场景下,SSE 可以用于实现简单的聊天应用。
  • 服务器监控:实时获取服务器运行状态、日志等信息。

客户端实现

在客户端,可以通过创建 EventSource 对象来连接到 SSE 服务器端点,并监听 message 事件来接收服务器发送的数据。

服务器端实现

在服务器端,可以使用各种框架来实现 SSE。例如,在 Spring 中,可以通过 SseEmitter 类来发送事件。服务器需要定期发送数据,并且需要正确处理连接的关闭和异常情况。

特点

  • 轻量级:相比于 WebSocket,SSE 更简单,只需要设置 HTTP 头部。
  • 单向通信:仅支持服务器到客户端的数据传输。
  • 自动重连:如果连接断开,客户端会自动尝试重连。
  • 只支持文本数据:如果需要发送二进制数据,需要进行编码。

限制

  • 浏览器兼容性:虽然现代浏览器普遍支持 SSE,但 IE 和早期版本的 Edge 不支持。
  • 只支持文本:需要发送二进制数据时,需要进行编码。

与 WebSocket 的比较

  • 通信方向:SSE 只支持服务器向客户端推送数据,而 WebSocket 支持双向通信。
  • 协议:SSE 基于 HTTP 协议,而 WebSocket 有自己的协议。
  • 浏览器兼容性:SSE 在现代浏览器中得到良好支持,但不支持 IE。WebSocket 得到了更广泛的浏览器支持。
  • 性能:对于大规模的实时数据推送,WebSocket 可能提供更好的性能,因为它是全双工的。
  • 用途:SSE 适合轻量级的推送任务,而 WebSocket 适合需要复杂交互的应用。
  • 实现复杂度:SSE 更容易实现,因为它不需要握手过程。
  • 数据类型:SSE 主要用于文本数据,而 WebSocket 可以更有效地处理二进制数据。
  • 适用场景:SSE 适用于需要服务器向客户端推送实时信息的场景;WebSocket 更通用,适用于需要实现双向通信的广泛场景。
  • 资源损耗对比:SSE 消耗更少的资源,因为它只需要服务器向客户端推送数据,而不需要处理来自客户端的数据。这使得 SSE 在资源有限的环境中更有优势。WebSocket 会消耗更多资源,因为它需要处理双向通信,这会涉及到更多的数据传输和状态管理。

SSE 是一种有效的服务器推送技术,适用于不需要从客户端向服务器发送消息的场景。它通过保持一个长连接来实现服务器向客户端的实时数据更新。

在 Java Spring 框架中的使用

在 Spring 框架中,可以通过 SseEmitter 类来实现 SSE。以下是一个简单的使用示例:

import org.springframework.http.MediaType;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;import java.io.IOException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;@RestControllerpublic class SseController {private final ExecutorService executor = Executors.newSingleThreadExecutor();@GetMapping(value = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public SseEmitter streamSseMvc() {SseEmitter emitter = new SseEmitter();executor.execute(() -> {try {for (int i = 0; i < 10; i++) {// 模拟数据处理Thread.sleep(1000);emitter.send("Message " + i);}emitter.complete();} catch (IOException | InterruptedException e) {emitter.completeWithError(e);}});return emitter;}}

客户端实现

在客户端,可以通过 JavaScript 的 EventSource 对象来连接到 SSE 服务器端点,并监听 message 事件来接收服务器发送的数据。

<!DOCTYPE html><html><head><title>SSE with Spring Boot</title></head><body><h1>Receiving Server-Sent Events</h1><div id="messages"></div><script>var eventSource = new EventSource('/sse');eventSource.onmessage = function(event) {var messages = document.getElementById('messages');var message = document.createElement('div');message.textContent = 'Message from server: ' + event.data;messages.appendChild(message);};eventSource.onerror = function(event) {console.error('EventSource failed:', event);eventSource.close();};</script></body></html>

注意事项

  • 当客户端断开连接时,SseEmitter 会抛出 IOException,因此务必捕获并处理这种异常。通常情况下我们会调用 emitter.complete() 或 emitter.completeWithError() 来关 SseEmitter
  • SSE 连接是持久性的,长时间保持连接可能需要处理超时和重连问题。
  • 考虑到资源消耗,对于大量的并发客户端,可能需要采用连接池或者其他优化策略。

相关文章:

  • 【架构】前台、中台、后台
  • Jmeter关联,断言,参数化
  • 如何使用ssm实现基于JavaWeb的个人健康信息管理系统
  • 嵌入式单片机底层原理详解
  • 力扣30. 串联所有单词的子串
  • 【Linux】部署 flask
  • Gateway和VirtualService
  • 揭秘顶级 RAG 技术,不可错过的关键知识!
  • C语言实现归并排序(Merge Sort)
  • oracle 定时任务每月27号到月底
  • AccessClient在MacOS14 (sonoma)闪退无法调用远程桌面
  • Spark 性能优化高频面试题及答案
  • 国产操作系统(统信UOS)网络安全等级保护基础安全加固
  • 杨辉三角-C语言
  • word中的表格全部设置宽度100%
  • 【5+】跨webview多页面 触发事件(二)
  • 78. Subsets
  • Apache的80端口被占用以及访问时报错403
  • css的样式优先级
  • emacs初体验
  • express + mock 让前后台并行开发
  • HTTP那些事
  • puppeteer stop redirect 的正确姿势及 net::ERR_FAILED 的解决
  • Python中eval与exec的使用及区别
  • session共享问题解决方案
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 聊聊sentinel的DegradeSlot
  • 前端面试题总结
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 微服务核心架构梳理
  • 系统认识JavaScript正则表达式
  • 优秀架构师必须掌握的架构思维
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • 浅谈sql中的in与not in,exists与not exists的区别
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • # 数论-逆元
  • $.ajax,axios,fetch三种ajax请求的区别
  • $NOIp2018$劝退记
  • (1)Jupyter Notebook 下载及安装
  • (7) cmake 编译C++程序(二)
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (七)Appdesigner-初步入门及常用组件的使用方法说明
  • (四)鸿鹄云架构一服务注册中心
  • (五)网络优化与超参数选择--九五小庞
  • (一)80c52学习之旅-起始篇
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • (转)甲方乙方——赵民谈找工作
  • ***原理与防范
  • .mysql secret在哪_MYSQL基本操作(上)
  • .NET C# 配置 Options
  • .NET HttpWebRequest、WebClient、HttpClient
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)