Spring Boot中集成 SSE

2024-05-25 10:04
文章标签 java spring boot 集成 sse

本文主要是介绍Spring Boot中集成 SSE,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  1. SSE简介
  2. SSE原理
  3. SSE的使用场景
  4. 在Spring Boot中集成SSE
    • 创建Spring Boot项目
    • 添加依赖
    • 创建SSE控制器
    • 前端使用SSE
    • 详细案例:股票价格实时推送
  5. 总结

SSE简介

服务器发送事件(Server-Sent Events,SSE)是一种在HTTP协议上实现的服务器推送技术。它允许服务器单向地将实时更新推送到客户端。与WebSocket不同,SSE是基于HTTP协议的简化实现,非常适合需要从服务器向客户端单向推送数据的场景。

SSE原理

SSE通过HTTP协议的一个长连接来实现服务器到客户端的单向数据流。客户端通过发送一个普通的HTTP请求来建立连接,服务器接收到请求后,保持连接不断开,并通过这个连接持续地发送事件。客户端使用JavaScript的EventSource API来处理这些事件。

SSE的使用场景

SSE适用于以下应用场景:

  • 实时通知:如邮件通知、系统消息推送。
  • 实时更新:如股票行情、新闻更新。
  • 监控和仪表盘:实时监控数据的展示。
  • 社交媒体更新:如实时评论和点赞。

在Spring Boot中集成SSE

创建Spring Boot项目

首先,使用Spring Initializr或IDE(如IntelliJ IDEA)创建一个新的Spring Boot项目,选择合适的Spring Boot版本(如2.5.x或3.x),并添加以下依赖:

  • Spring Web

添加依赖

pom.xml中添加Spring Web的依赖:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 其他依赖 -->
</dependencies>

创建SSE控制器

创建一个控制器来处理SSE连接和事件推送。

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.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;@RestController
public class SseController {@GetMapping("/sse")public SseEmitter handleSse() {// 创建一个新的SseEmitter实例,超时时间为30秒SseEmitter emitter = new SseEmitter(30_000L);// 创建一个ScheduledExecutorService来定时发送事件ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);// 每秒发送一个当前时间的消息executor.scheduleAtFixedRate(() -> {try {// 发送事件,事件名称为"message",数据为当前时间戳emitter.send(SseEmitter.event().name("message").data("Current Time: " + System.currentTimeMillis()));} catch (IOException e) {// 发送失败时完成该Emitteremitter.completeWithError(e);}}, 0, 1, TimeUnit.SECONDS);// 在30秒后完成该Emitterexecutor.schedule(() -> emitter.complete(), 30, TimeUnit.SECONDS);return emitter;}
}

前端使用SSE

在前端使用JavaScript的EventSource来接收服务器发送的事件:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SSE Demo</title>
</head>
<body><h1>SSE Demo</h1><div id="messages"></div><script>// 创建一个新的EventSource实例,连接到服务器的/sse端点const eventSource = new EventSource("/sse");// 当收到服务器发送的消息时,执行此函数eventSource.onmessage = function(event) {// 获取消息展示的divconst messagesDiv = document.getElementById("messages");// 创建一个新的div元素来展示新消息const newMessage = document.createElement("div");newMessage.textContent = event.data; // 设置div的文本内容为事件数据messagesDiv.appendChild(newMessage); // 将新消息添加到消息展示div中};// 当发生错误时,执行此函数eventSource.onerror = function(error) {console.error("EventSource failed: ", error);eventSource.close(); // 关闭EventSource};</script>
</body>
</html>

详细案例:股票价格实时推送

假设我们需要实现一个股票价格实时推送的功能,服务器定期向客户端发送股票价格更新。

创建StockService类

模拟股票价格变化的服务类。

import org.springframework.stereotype.Service;import java.util.Random;@Service
public class StockService {private Random random = new Random();// 模拟获取股票价格的方法public double getStockPrice(String symbol) {// 返回一个随机价格return 100 + (random.nextDouble() * 50);}
}
更新SseController类

使用StockService类来推送股票价格。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;@RestController
public class SseController {private final StockService stockService;// 使用构造器注入StockServicepublic SseController(StockService stockService) {this.stockService = stockService;}@GetMapping("/sse/{symbol}")public SseEmitter handleSse(@PathVariable String symbol) {// 创建一个新的SseEmitter实例,超时时间为30秒SseEmitter emitter = new SseEmitter(30_000L);// 创建一个ScheduledExecutorService来定时发送事件ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);// 每秒发送一个股票价格更新executor.scheduleAtFixedRate(() -> {try {// 获取股票价格double price = stockService.getStockPrice(symbol);// 发送事件,事件名称为"stock-price",数据为股票价格emitter.send(SseEmitter.event().name("stock-price").data("Stock Price of " + symbol + ": " + price));} catch (IOException e) {// 发送失败时完成该Emitteremitter.completeWithError(e);}}, 0, 1, TimeUnit.SECONDS);// 在30秒后完成该Emitterexecutor.schedule(() -> emitter.complete(), 30, TimeUnit.SECONDS);return emitter;}
}
更新前端代码

在前端展示股票价格更新。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Stock Price SSE Demo</title>
</head>
<body><h1>Stock Price SSE Demo</h1><input type="text" id="symbol" placeholder="Enter stock symbol"><button onclick="connect()">Connect</button><div id="messages"></div><script>let eventSource;function connect() {const symbol = document.getElementById("symbol").value;if (eventSource) {eventSource.close(); // 关闭已有的连接}// 创建一个新的EventSource实例,连接到服务器的/sse/{symbol}端点eventSource = new EventSource("/sse/" + symbol);// 当收到服务器发送的消息时,执行此函数eventSource.onmessage = function(event) {// 获取消息展示的divconst messagesDiv = document.getElementById("messages");// 创建一个新的div元素来展示新消息const newMessage = document.createElement("div");newMessage.textContent = event.data; // 设置div的文本内容为事件数据messagesDiv.appendChild(newMessage); // 将新消息添加到消息展示div中};// 当发生错误时,执行此函数eventSource.onerror = function(error) {console.error("EventSource failed: ", error);eventSource.close(); // 关闭EventSource};}</script>
</body>
</html>

这篇关于Spring Boot中集成 SSE的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1001192

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Debezium 与 Apache Kafka 的集成方式步骤详解

《Debezium与ApacheKafka的集成方式步骤详解》本文详细介绍了如何将Debezium与ApacheKafka集成,包括集成概述、步骤、注意事项等,通过KafkaConnect,D... 目录一、集成概述二、集成步骤1. 准备 Kafka 环境2. 配置 Kafka Connect3. 安装 D

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.