开发经验服务器单向推送——SSE
Posted 叁滴水
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开发经验服务器单向推送——SSE相关的知识,希望对你有一定的参考价值。
背景
目前广州疫情,每次出行都需要出示健康码,有的小伙伴比较机智,为了更加快速的通行,对于健康码进行截图,这样就可以很快的打开健康码。但是这样也违背了地铁查看健康码的初衷,很可能存在有的人黄码,然后找朋友的绿码出行。
为了防止这一情况。检查人员需要看到健康码的时间是变化的,才放行。
如上图时间,在网络正常的时候,时间会实时变化,断开网络之后,网络会卡住。这个时间肯定是服务器时间。因为如果是本地时间,可以通过修改自己手机时间进行修改。
问题来了,联网变化,断网暂定,这个功能如何实现呢?脑回路中迅速转动后得出如下结论
- ajax轮询,每隔一段时间就请求一次服务器,然后更新页面的时间。
- websocket推送,可以建立长连接,然后通过服务器进行推送。
- SSE单向推送。
这种情况,笔者以为ajax轮询的方式很鸡肋,当然压力小的情况下,简单的做一个小功能还是可以的;websocket只是推送一个服务器时间,未免有点太重量级了。因此,这个场景非常适合SSE的使用。
Server-sent Events(sse)与长轮询机制类似,区别是每个连接不只发送一个消息。客户端发送一个请求,服务端保持这个连接直到有新消息发送回客户端,仍然保持着连接,这样连接就可以消息的再次发送,由服务器单向发送给客户端。
SSE本质是发送的不是一次性的数据包,而是一个数据流。可以使用 HTTP 301 和 307 重定向与正常的 HTTP 请求一样。服务端连续不断的发送,客户端不会关闭连接,如果连接断开,浏览器会尝试重新连接。如果连接被关闭,客户端可以被告知使用 HTTP 204 无内容响应代码停止重新连接。
sse只适用于高级浏览器,ie不支持。因为ie上的XMLHttpRequest对象不支持获取部分的响应内容,只有在响应完成之后才能获取其内容。
这时SSE与WebSocket的区别可以简单的认为,SSE是单向服务器推送到客户端,WebSocket是双工通信。
SSE
WebSocket
SSE实现时间下发功能
代码实现
一个简单的springboot工程
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
新建controller
@Slf4j
@RestController
public class SSEController
{
@GetMapping ("/stream-sse-mvc")
public SseEmitter streamSseMvc() {
SseEmitter emitter = new SseEmitter();
ExecutorService sseMvcExecutor = Executors.newSingleThreadExecutor();
sseMvcExecutor.execute(() -> {
try {
for (int i = 0; i<10; i++) {
SseEmitter.SseEventBuilder event = SseEmitter.event()
.data("我是一个data现在的时间是" + LocalTime.now().toString());
// .id(String.valueOf(i))
// .name("sse event - mvc");
emitter.send(event);
Thread.sleep(1000);
}
} catch (Exception ex) {
emitter.completeWithError(ex);
}
});
return emitter;
}
}
浏览器请求该controller即可。真实场景,如果汉字乱码在请求头添加Content-Type: text/event-stream;charset=UTF-8
即可。
此功能为,每个一秒,返回服务器时间。
SSE是一个单向推送,适合像推送服务器时间的这种简单场景。
以上是关于开发经验服务器单向推送——SSE的主要内容,如果未能解决你的问题,请参考以下文章
How Javascript works (Javascript工作原理) 深入理解 WebSockets 和带有 SSE 机制的HTTP/2 以及正确的使用姿势