序言
服务器推送技术在一些需要实时数据的开发场景会被广泛使用,要获得实时数据,前端轮询的方式明显是被摒弃的,大部分人第一时间想到的就是websocket。之前的一个项目也是用的websocket,但是后期造成了会话缓存不断变大的问题,花了很多时间来解决。因此我就想着找一个替代websocket,简单好用的技术,因此便发现了SSE。以下记录学习SSE踩的坑,尤其看了很多博客和教学视频,带来的SSE就是一直轮询的疑惑。
如果对websocket有兴趣,参考博客:SpringBoot2.0集成WebSocket,实现后台向前端推送信息
SSE:Server send Event:服务端发送事件【划重点,服务端推送,而不是轮询请求】。
1、错误用法
之所以叫错误用法,是我觉得这不是SSE的真正使用方式,而不是使用错误。
当你打算了解SSE技术,百度搜了各种博客或者视频,他们会给你一个Controller代码,告诉你SSE的消息格式是 "data:" + 消息 + "\n\n"
,然后写个页面来接收消息,再贴个F12控制台的图片说SSE就是轮询请求,比如下面的:
Controller代码:
1 |
|
页面:
1 |
|
页面结果:
这个结果就是我根据网上很多博客和视频实现的效果,乍一看,是页面不停的请求才实现了数据刷新的效果。但是,不是说好了SSE是一种服务端向页面推送数据的技术吗?这明明就是页面在发请求啊??还好我之前用过websocket,不然还真是被忽悠了,破绽就在页面数据打印上面一行的“开启”两个字,这是在open(也就是创建页面与服务端连接)的时候才会有的,按理说只会在进入页面就与服务器创建连接,仅一次(如果没有设置超时时间的话),而不是一直在连接。
之前使用websocket的时候,大概流程应该是:打开页面,页面会以一个id(或者称之为通道)与服务端连接,而服务端就可以通过这个id来向页面推送信息。而以上事例的代码完全没有体现出服务端推送消息的点在哪里??如果SSE仅限于此,那它还有存在的必要吗?还不如直接在页面上进行定时请求。
2、正确使用
上面的事例明显不能满足我对SSE的期望,继续百度,终于让我找到了我想要的真正的SSE。
参考博客:springboot SseEmitter 消息推送
这里我们不再使用原生的SSE,而是经过封装SseEmitter(就在web包下,不需要添加新的依赖),使用SseEmitter我们不再需要在@GetMapping上写produces = “text/event-stream; charset=utf-8”,也不需要在返回数据里拼”data:”和”\n\n”的格式。
工具类:
1 | public class SseEmitterServer { |
有部分博客在创建连接的时候,设置的超时时间太短,造成页面一直重连,就会出现和上面错误用法类似的情况,页面一直在请求接口。
页面:
1 |
|
项目启动成功之后,我使用了四个浏览器进行访问,分别是谷歌、360急速、星愿和微软的edge,遗憾的是edge不支持SSE。
- 测试单个发送:
- 测试多个发送
- 测试发送所有
3、总结
相对于可以双向(服务端和客户端)的websocket,SSE仅能实现服务端向客户端推送消息,但是一般情况也足够使用了,使用方面也是比较简单的,以上内容仅是我个人在学习SSE中的看法。
- 本文作者: tenyears
- 本文链接: https://tenyears94.gitee.io/2020/11/11/SpringBoot使用SSE推送消息/
- 版权声明: 本博客所有文章转载请注明出处!