SSE和WebSocket的区别
- 数据推送方面
- SSE 是服务端像客户端的单向通信的技术。
- WebSocket是双向通讯的技术
- 协议方面
- SSE是基于HTTP协议的长连接,超时后可以自动重连
- WebSocket是基于ws协议的,建立双向连接实现通讯的
- 订阅的返回值必须是
SseEmitter
,返回的数据类型为事件流。执行返回类型的的话需要配置produces = {MediaType.TEXT_EVENT_STREAM_VALUE}
。也可以不配置,请求会自动匹配。 - 消息的发送,必须通过返回的
SseEmitter
,调用send()方法。由于需要实时推送,所以需要将创建的SseEmitter
缓存起来,随时推送消息。 SseEmitter
空参构造函数默认的超时时间为60s,也可以通过构造参数设置超时时间。案例中超时时间15s。如果设置成0,则表示永不超时。- Header中
Last-Event-ID
参数为当前连接最新推送消息的ID,该ID可以自定义。消息推送之后,客户端重连之后,Header中会自动携带此参数(Last-Event-ID
)。 SseEmitter
连接可以注册onCompletion
【关闭】,onTimeOut
【超时】,onError
【错误】事件的回调。
注意事项:
- map里面存放客户端的ID和连接。
- 因为SSE连接会超时,超时的连接关闭之后会通过回调删除连接,所以重新连接的连接不会受到消息的推送。所以使用doneMap记录已经推送的客户端。自动连接的新连接补发消息。
建立连接
new EventSource('/foo/sse')
建立连接/订阅消息,页面打开,方法执行会根据订阅的路径请求服务端获取连接。
页面关闭的事件
window.onbeforeunload
监听页面的关闭,但是存在兼容性问题,或者页面异常的关闭都不会触发该方法。所以此方法不可靠。
SSE的使用要注意过期时间的设置,使用了过期时间,就要考虑客户端重连的消息的丢失问题。
使用了永不过期就要考虑防止客户端连接过多造成的OOM