在很多场景中客户端和服务端简单的一次交互无法满足需求,因此产生了长连接的多种实践,主要有以下几种
- 长轮询
- sse
- websocket
- grpc双向流
长轮询无需赘述,实现最简单,但效率最低,一般在项目mvp阶段或流量很小的项目或功能中使用
sse
Server-sent Events 规范是 HTML 5 规范的一个组成部分,该规范比较简单,主要由两个部分组成:第一个部分是服务器端与浏览器端之间的通讯协议,第二部分则是在浏览器端可供 JavaScript 使用的 EventSource 对象。通讯协议是基于纯文本的简单协议。服务器端的响应的内容类型是"text/event-stream"。响应文本的内容可以看成是一个事件流,由不同的事件所组成。每个事件由类型和数据两部分组成,同时每个事件可以有一个可选的标识符。不同事件的内容之间通过仅包含回车符和换行符的空行("\r\n")来分隔。每个事件的数据可能由多行组成。代码清单 1 给出了服务器端响应的示例。
1. 服务器端响应的示例:
kotlin
`data: first event`
`data: second event`
`id: 100`
`event: myevent`
`data: third event`
`id: 101`
`: this is a comment`
`data: fourth event`
`data: fourth event continue`
sse实现很简单,局限是只能支持服务端向客户端发送消息。常见的使用场景是股票看板和大模型应用。但要注意的是部分浏览器可能不支持sse
websocket
WebSocket 是 HTML5 一种新的协议。它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯,它建立在 TCP 之上,协议定义与http类似,例如ws://yourdomain:port/path 客户端与服务端都需要维护一个套接字
它与sse的区别是可以全双工通信,且所有主流浏览器都支持。因此大部分双向的通信场景都使用websocket协议,或者基于websocket修改的协议。如IM即时通讯,直播聊天框 但由于服务端有大量微服务,且服务都有大量实例,因此需要解决内部消息传递的问题
grpc双向流
基于 HTTP/2,支持多路复用(Multiplexing)、头部压缩和流式传输。而websocket是基于HTTP/1.1 grpc一般只用在服务端微服务间通信,主要原因是所有主流浏览器都支持websocket,且websocket是文本协议可读性强,且已经有成熟的调试工具。而grpc的优势是压缩效率高,交互schema严格定义在protobuf中,可维护性强,在内部开发人员的合作中清晰明了