如何通过SpringBoot整合SSE实现后端主动向客户端推送数据?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1128个文字,预计阅读时间需要5分钟。
SpringBoot整合SSE(Server-Sent Events)实现后端主动向前端推送数据(目录)核心代码依赖后端接收SSE连接
SpringBoot整合SSE(Server-Sent Events)可以实现后端主动向前端推送数据
(目录)
核心代码
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
后端接收sse连接
@Controller
@RequestMapping("/sse")
public class IndexController {
/**
* 创建SSE连接
*
* @return
*/
@GetMapping(path = "/connect")
public SseEmitter sse() {
SseEmitter sseEmitter = new SseEmitter();
// 发送一个注释,响应前端请求
sseEmitter.send(SseEmitter.event().comment("welcome"));
return sseEmitter;
}
}
前端浏览器代码
// 连接服务器
var sseSource = new EventSource("localhost:8080/sse/connect");
// 连接打开
sseSource.onopen = function () {
console.log("连接打开");
}
// 连接错误
sseSource.onerror = function (err) {
console.log("连接错误:", err);
}
// 接收到数据
sseSource.onmessage = function (event) {
console.log("接收到数据:", event);
handleReceiveData(JSON.parse(event.data))
}
完整代码
项目目录
$ tree -I target -I test
.
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── example
│ └── demo
│ ├── Application.java
│ ├── controller
│ │ └── IndexController.java
│ ├── entity
│ │ └── Message.java
│ ├── service
│ │ ├── SseService.java
│ │ └── impl
│ │ └── SseServiceImpl.java
│ └── task
│ └── SendMessageTask.java
└── resources
├── application.yml
├── static
└── templates
└── index.html
完整依赖 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="maven.apache.org/POM/4.0.0" xmlns:xsi="www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="maven.apache.org/POM/4.0.0 maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<mybatis-plus.version>3.5.2</mybatis-plus.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
前端代码 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
</head>
<body>
<div id="result"></div>
<script>
// 连接服务器
var sseSource = new EventSource("localhost:8080/sse/connect");
// 连接打开
sseSource.onopen = function () {
console.log("连接打开");
}
// 连接错误
sseSource.onerror = function (err) {
console.log("连接错误:", err);
}
// 接收到数据
sseSource.onmessage = function (event) {
console.log("接收到数据:", event);
handleReceiveData(JSON.parse(event.data))
}
// 关闭链接
function handleCloseSse() {
sseSource.close()
}
// 处理服务器返回的数据
function handleReceiveData(data) {
let div = document.createElement('div');
div.innerHTML = data.data;
document.getElementById('result').appendChild(div);
}
// 通过localhost:8080/sse/sendMessage', {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(data)
})
}
</script>
</body>
</html>
定义一个返回数据 Message.java
package com.example.demo.entity;
import lombok.Data;
@Data
public class Message {
private String data;
private Integer total;
}
定义sse接口 SseService.java
package com.example.demo.service;
import com.example.demo.entity.Message;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
public interface SseService {
SseEmitter connect(String uuid);
void sendMessage(Message message);
}
实现sse接口 SseServiceImpl.java
package com.example.demo.service.impl;
import com.example.demo.entity.Message;
import com.example.demo.service.SseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.github.com/mouday/spring-boot-demo/SpringBoot-SSE
参考文章
- developer.mozilla.org/zh-CN/docs/Web/API/EventSource
- Server-Sent Events 教程
- 推送数据?也许你不需要 WebSocket
本文共计1128个文字,预计阅读时间需要5分钟。
SpringBoot整合SSE(Server-Sent Events)实现后端主动向前端推送数据(目录)核心代码依赖后端接收SSE连接
SpringBoot整合SSE(Server-Sent Events)可以实现后端主动向前端推送数据
(目录)
核心代码
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
后端接收sse连接
@Controller
@RequestMapping("/sse")
public class IndexController {
/**
* 创建SSE连接
*
* @return
*/
@GetMapping(path = "/connect")
public SseEmitter sse() {
SseEmitter sseEmitter = new SseEmitter();
// 发送一个注释,响应前端请求
sseEmitter.send(SseEmitter.event().comment("welcome"));
return sseEmitter;
}
}
前端浏览器代码
// 连接服务器
var sseSource = new EventSource("localhost:8080/sse/connect");
// 连接打开
sseSource.onopen = function () {
console.log("连接打开");
}
// 连接错误
sseSource.onerror = function (err) {
console.log("连接错误:", err);
}
// 接收到数据
sseSource.onmessage = function (event) {
console.log("接收到数据:", event);
handleReceiveData(JSON.parse(event.data))
}
完整代码
项目目录
$ tree -I target -I test
.
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── example
│ └── demo
│ ├── Application.java
│ ├── controller
│ │ └── IndexController.java
│ ├── entity
│ │ └── Message.java
│ ├── service
│ │ ├── SseService.java
│ │ └── impl
│ │ └── SseServiceImpl.java
│ └── task
│ └── SendMessageTask.java
└── resources
├── application.yml
├── static
└── templates
└── index.html
完整依赖 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="maven.apache.org/POM/4.0.0" xmlns:xsi="www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="maven.apache.org/POM/4.0.0 maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<mybatis-plus.version>3.5.2</mybatis-plus.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
前端代码 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
</head>
<body>
<div id="result"></div>
<script>
// 连接服务器
var sseSource = new EventSource("localhost:8080/sse/connect");
// 连接打开
sseSource.onopen = function () {
console.log("连接打开");
}
// 连接错误
sseSource.onerror = function (err) {
console.log("连接错误:", err);
}
// 接收到数据
sseSource.onmessage = function (event) {
console.log("接收到数据:", event);
handleReceiveData(JSON.parse(event.data))
}
// 关闭链接
function handleCloseSse() {
sseSource.close()
}
// 处理服务器返回的数据
function handleReceiveData(data) {
let div = document.createElement('div');
div.innerHTML = data.data;
document.getElementById('result').appendChild(div);
}
// 通过localhost:8080/sse/sendMessage', {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(data)
})
}
</script>
</body>
</html>
定义一个返回数据 Message.java
package com.example.demo.entity;
import lombok.Data;
@Data
public class Message {
private String data;
private Integer total;
}
定义sse接口 SseService.java
package com.example.demo.service;
import com.example.demo.entity.Message;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
public interface SseService {
SseEmitter connect(String uuid);
void sendMessage(Message message);
}
实现sse接口 SseServiceImpl.java
package com.example.demo.service.impl;
import com.example.demo.entity.Message;
import com.example.demo.service.SseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.github.com/mouday/spring-boot-demo/SpringBoot-SSE
参考文章
- developer.mozilla.org/zh-CN/docs/Web/API/EventSource
- Server-Sent Events 教程
- 推送数据?也许你不需要 WebSocket

