相信很多开发者在实际工作中一定遇到过要将数据实时展示到数据大屏上的需求,在一般情况下,数据能够在页面上展示,都是通过前端调用HTTP请求来进行数据渲染,很多人采用的方式都是通过定时调用接口来实现数据的展示。但是这种方式实现实时展示其实是伪实时,也就是并不是实时数据展示。
这时候就有人提出来使用WebSocket进行展示。但是WebSocket有一个弊端,就是如果数据在长时间内没有更新WebSocket的没有进行通信的话,连接就会自动断开,这个时候也不能做到完全的实时。
既然这样,下面我们就来介绍一种新的实现方式。SSE(Server-Sent Event),服务器推送事件。
什么是SSE?
SSE是指Server-Sent Event,服务器推送事件,它是一种实现客户端和服务器之间的单向实时通信技术,允许服务器通过一个普通的HTTP连接向客户端不断的发送数据,而不需要客户端再次发送请求的方式。
其工作原理如下。
第一步、客户端通过HTTP请求与服务端建立连接,这个连接中包含了一个特殊的请求头部信息Accept: text/event-stream,这个标识用来表示客户端希望能够与服务器发送SSE事件。
第二步、服务端收到了客户端的请求之后,需要建立一个HTTP的连接,然后通过这个连接向客户端发送事件流信息。需要注意的是每个事件都是一个文本消息,并且采用特殊的文本格式,通常情况是以如下的格式来进行发送
event: eventName、data: eventData
第三步、当客户端收到了事件流信息之后,会监听EventSource对象onmessage事件来对接收到的事件进行处理,然后客户端根据接收到的事件类型和数据来选择更新页面操作或者是执行其他的操作。
通过上述的步骤,就可以实现客户端与服务端的实时数据通信。SSE主要实现了服务端向客户端的主动的发送信息,例如实时消息通知、实时监控、实时数据展示等场景,相比于长连接轮询、WebSocket来讲SSE具有简单易用、兼容性好等特点。
下面我们就来看看在SpringBoot应用中如何整合SSE来实现实时数据大屏功能。
SpringBoot整合SSE实现数据实时展示功能?
第一步、添加POM依赖
需要再POM文件中添加对应的依赖项,如下所示。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
第二步、创建控制类来处理SSE请求并发送实时展示数据
@RestController
public class SSEController {
private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
@GetMapping(value = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter streamSseEvents() {
SseEmitter emitter = new SseEmitter();
executorService.scheduleAtFixedRate(() -> {
try {
// 模拟生成实时数据
String eventData = "Current time: " + System.currentTimeMillis();
emitter.send(SseEmitter.event().data(eventData));
} catch (IOException e) {
emitter.completeWithError(e);
}
}, 0, 1, TimeUnit.SECONDS); // 每秒发送一次数据
// 客户端关闭连接时结束发送
emitter.onCompletion(() -> executorService.shutdown());
return emitter;
}
}
在这个示例中,我创建了一个名为SSEController的REST控制器类,其中包含了一个streamSseEvents方法来处理 SSE 请求。在该方法中,我们使用SseEmitter来创建一个SSE事件发送器,并通过定时任务每秒向客户端发送一次实时数据。
最后,启动Spring Boot应用程序,并访问/sse路径,客户端将会收到实时的数据流。
Vue前端实现?
以Vue为例来做一个简单的前端数据展示功能,通过SSE来完成数据的接收和展示。
要想实现该功能,首先需要安装EventSource相关的插件,用来在浏览器中接收到SSE数据,如下所示。
npm install eventsource
编写对应的Vue组件来进行SSE数据处理
<template>
<div>
<h1>Real-Time Data</h1>
<ul>
<li v-for="eventData in eventDataList" :key="eventData.id">{{ eventData.data }}</li>
</ul>
</div>
</template>
<script>
import EventSource from 'eventsource';
export default {
data() {
return {
eventDataList: []
};
},
mounted() {
// 建立 SSE 连接
this.setupSSE();
},
methods: {
setupSSE() {
const eventSource = new EventSource('/sse');
// 监听 SSE 事件
eventSource.addEventListener('message', (event) => {
const eventData = { id: Date.now(), data: event.data };
this.eventDataList.push(eventData);
});
// 处理连接关闭事件
eventSource.addEventListener('error', (event) => {
if (event.readyState === EventSource.CLOSED) {
console.log('SSE connection closed.');
}
});
}
}
};
</script>
在上面这个例子中,通过创建一个Vue的组件来接收并展示SSE发送的数据,在组件的mounted函数中调用setupSSE方法来建立起一个SSE连接,并且开始监听到SSE事件,当接收到服务端发送的新的事件之后,将数据添加到eventDataList中,然后通过for循环来遍历数据进行渲染。最后可以在Vue的其他地方调用该组件来完成数据的展示操作。
总结
通过上述的操作,我们就可以完成通过SSE来实现的数据实时展示功能。通过SSE技术可以完成实现服务器向客户端推送实时更新的数据,例如实时通知、实时监控、即时聊天等场景,相比于传统的长轮询,WebSocket等技术SSE实现实时数据展示更加的稳定可靠,高效易用。