Spring Boot整合SSE实时通信

devtools/2025/1/12 23:21:05/

服务器发送事件(Server-Sent Events, SSE)是一种让网页实时更新的技术。想象一下,您正在浏览一个网页,而这个网页需要在有新信息时自动更新,比如新闻网站的最新消息、社交媒体的通知或股票市场的价格变动。SSE使得这种实时更新成为可能,并且它是通过普通的HTTP连接实现的,这意味着它不需要任何特殊的协议或复杂的设置。

SSE的主要特点

  • 基于HTTP:SSE使用标准的HTTP协议来通信,因此它很容易集成到现有的网络架构中,无需额外配置。

  • 单向数据流:与WebSocket不同,SSE只允许服务器向客户端推送数据,而不能反过来。这对于只需要从服务器接收更新的场景非常有用,例如直播评论或通知提醒。

  • 自动重连:如果由于某种原因连接中断了,浏览器会自动尝试重新连接到服务器,确保用户不会错过任何更新。

  • 自定义事件类型:除了基本的数据推送外,SSE还允许服务器发送特定类型的事件,这样客户端就可以根据不同的事件类型做出相应的反应。

  • 轻量级和简单:相比其他如WebSocket等技术,SSE的实现更为简单,适合不需要双向通信的应用场景。对于开发者来说,这意味着更少的代码和更容易维护的系统。

添加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

创建SSE控制器

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
@CrossOrigin
@RestController
@RequestMapping("sse")
public class SseController {private final ExecutorService executorService = Executors.newCachedThreadPool();@GetMapping("/handleSse")public SseEmitter handleSse() {SseEmitter emitter = new SseEmitter();executorService.execute(() -> {try {for (int i = 0; i < 10; i++) {emitter.send(SseEmitter.event().name("message").data("数据库来消息了" + i));Thread.sleep(1000);}emitter.complete();} catch (IOException | InterruptedException e) {emitter.completeWithError(e);}});return emitter;}
}

客户端实现

<!DOCTYPE html>
<html>
<body>
<h1>SSE Demo</h1>
<div id="messages"></div>
<button id="connectButton">连接</button>
<button id="disconnectButton" disabled>断开连接</button><script>let eventSource = null;const messages = document.getElementById('messages');const connectButton = document.getElementById('connectButton');const disconnectButton = document.getElementById('disconnectButton');function connect() {if (eventSource) return; // 如果已经连接,则不重复创建eventSource = new EventSource('http://localhost:8081/items/handleSse');eventSource.onmessage = function(event) {const message = document.createElement('p');message.textContent = event.data;messages.appendChild(message);};eventSource.onerror = function(error) {console.error('EventSource failed:', error);disconnect(); // 在发生错误时也尝试断开连接};// 禁用连接按钮,启用断开连接按钮connectButton.disabled = true;disconnectButton.disabled = false;}function disconnect() {if (!eventSource) return; // 如果没有连接,则不执行任何操作eventSource.close();eventSource = null;// 启用连接按钮,禁用断开连接按钮connectButton.disabled = false;disconnectButton.disabled = true;}// 给按钮添加事件监听器connectButton.addEventListener('click', connect);disconnectButton.addEventListener('click', disconnect);
</script>
</body>
</html>

SSE(服务器发送事件)的优缺点及适用场景

优点
  • 简单易用:与WebSocket相比,SSE不需要复杂的握手过程。它的API设计直观,开发者可以更快速地上手。
  • 广泛的浏览器支持:几乎所有现代浏览器都支持SSE,包括手机和平板上的浏览器,这意味着它几乎可以在任何设备上工作。
  • 高效能和低延迟:相较于传统的轮询方式,SSE减少了不必要的请求次数,降低了服务器负担,并提高了数据更新的速度。
  • 自动重连功能:当网络连接中断时,浏览器会自动尝试重新连接到服务器,这简化了开发者的代码。
缺点
  • 单向通信限制:SSE只允许服务器向客户端推送信息,如果需要从客户端向服务器发送数据,则必须使用其他方法或技术。
  • 依赖HTTP长连接:虽然SSE优化了数据传输,但它的实现仍然基于HTTP连接,这可能在网络条件不佳或者通过某些代理服务器时遇到问题。
适用场景

SSE非常适合用于那些只需要服务器向客户端推送实时更新的应用场景,例如:

  • 实时新闻更新
  • 股票价格变动通知
  • 社交媒体动态提醒
  • 实时评论流
  • 系统状态监控
SSE vs. 轮询 vs. WebSocket
  • SSE与轮询的区别:传统轮询是客户端定时询问服务器是否有新数据,这种方式不仅增加了服务器的压力,也带来了较高的延迟。而SSE让服务器在有新数据时主动推送给客户端,减少了不必要的请求,提升了性能和用户体验。

  • SSE与WebSocket的对比

    • 通信方向:WebSocket支持双向通信,意味着客户端和服务器都可以随时发送消息;而SSE仅允许服务器向客户端推送信息。
    • 协议基础:WebSocket使用了自己的协议,而SSE基于标准的HTTP/HTTPS协议,使得SSE更容易部署并且更易于调试。
    • 连接管理:WebSocket建立后保持连接开放,直到被显式关闭;而SSE会在每次事件推送后自然断开,然后根据需要重新建立连接。
    • 兼容性和安全性:由于SSE基于HTTP协议,因此它在网络穿越方面表现得更好,并且能够更好地利用现有的安全机制(如HTTPS)。
选择建议
  • 轮询:适合于对实时性要求不高、只需要偶尔检查更新的场景。不过,这种方式会增加服务器的负载。
  • SSE:对于需要实时推送更新但不涉及双向通信的应用来说,SSE是一个很好的选择,因为它实现简单,而且浏览器兼容性好。
  • WebSocket:适用于需要频繁双向通信的应用,比如在线聊天室或多人在线游戏。

总之,选择哪种技术取决于您的具体需求和技术栈。如果您只需要服务器向客户端推送信息,并希望实现起来尽可能简单,那么SSE可能是最佳的选择。


http://www.ppmy.cn/devtools/149542.html

相关文章

2025年入职/转行网络安全,该如何规划?网络安全职业规划

网络安全是一个日益增长的行业&#xff0c;对于打算进入或转行进入该领域的人来说&#xff0c;制定一个清晰且系统的职业规划非常重要。2025年&#xff0c;网络安全领域将继续发展并面临新的挑战&#xff0c;包括不断变化的技术、法规要求以及日益复杂的威胁环境。以下是一个关…

计算机网络-数据链路层(交换机相关知识)

2.5交换机 2.5.1集线器和交换机的区别 使用集线器和双绞线的星型网络 使用集线器的以太网在逻辑上仍然是一个总线网&#xff0c;在各站共享总线资源&#xff0c;使用的还是CSMA/CD协议&#xff1b; 集线器只工作在物理层&#xff0c;他的每个接口仅简单的转发bit&#xff0c;…

二次雷达的详细介绍及代码示例

一、二次雷达的工作原理 二次雷达&#xff0c;又称空管雷达信标系统&#xff08;Air Traffic Control Radar Beacon System&#xff0c;ATCRBS&#xff09;&#xff0c;是一种无线电电子测位和辨认系统。它由地面询问雷达和飞机上的应答雷达&#xff08;又称雷达信标&#xff0…

C#调用MyLibxl来生成EXCEL的订货清单

在进销存里,基本上都有销售订单, 而这些订单的格式更是五花八门的。 一般情况用EXCEL的文件就可以表达出来,然后再通过打印EXCEL文件,就完成了整个订单的生成了。 下面就来生成如下面所示的销售收据: 接着需要编写下面这段代码: using MyLibxl; using MyLib.Libxl; u…

【Linux】UOS统信服务器本地yum源搭建实践

目录 ​编辑 一、下载镜像 二、服务器配置yum 一、下载镜像 镜像下载地址&#xff1a;https://www.chinauos.com/resource/download-server 二、服务器配置yum mkdir -p /yum/local mount -o loop /home/iso/uos-server-20-1060a-amd64.iso /yum/local/ 安装并配置httpd …

创建基本的 Electron 应用项目的详细步骤

创建一个基本的 Electron 应用项目的详细步骤。我们将从安装 Node.js 开始&#xff0c;然后创建项目文件夹并初始化 Electron 项目。 1. 安装 Node.js 首先&#xff0c;确保你已经安装了 Node.js 和 npm。你可以在终端中运行以下命令来检查是否已经安装&#xff1a; node -v…

C# 使用iText 编辑PDF

NetCore 创建、编辑PDF插入表格、图片、文字 NetCore 创建、编辑PDF插入表格、图片、文字(二) NetCore 创建、编辑PDF插入表格、图片、文字(三) 1&#xff0c;.net8 环境&#xff0c;引入 包 itext7 itext7.bouncy-castle-adapter 2,直接上代码 public class PDFEditor{public…

蓝桥杯历届真题 #分布式队列 (Java,C++)

文章目录 题目解读[蓝桥杯 2024 省 Java B] 分布式队列题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 思路完整代码 题目解读 题目链接 [蓝桥杯 2024 省 Java B] 分布式队列 题目描述 小蓝最近学习了一种神奇的队列&#xff1a;分布式队列。简单来说&#x…