构建实时Web应用程序,我们需要考虑如何将数据从服务端发送到客户端,目前有以下几种方法:
- 长/短轮询(客户端拉取)
- WebSocket(服务端推送)
- Server Send Event 服务端发送事件(服务端推送)
客户端拉取 - 客户端以一定的定期间隔向服务器请求更新;
服务端推送 - 服务端主动将更新推送到客户端;
长/短轮询
长轮询和短轮询都是以常规的 HTTP
协议进行通信,每一次通信都包含请求和响应。
通信过程
优缺点
长轮询(Long Polling):
优点:
- 实时性较高:长轮询可以让服务器在有新数据时立即推送给客户端,因此能够实现较高的实时性。
- 减少轮询频率:相比于传统的短轮询,长轮询可以减少客户端的轮询请求,从而减轻服务器的负担。
- 适合小规模实时通信:长轮询适合于小规模的实时通信需求,如聊天应用、社交媒体更新等。
缺点:
- 延迟:长轮询的实时性仍然受到延迟的影响,因为客户端必须等待服务器有数据可推送。
- 资源占用:服务器需要保持与每个客户端的连接,这可能占用大量资源。
- 连接断开处理:当客户端连接断开时,服务器需要处理重新连接的逻辑。
- 不适合大规模应用:长轮询在大规模应用中可能导致服务器不堪重负。
短轮询(Short Polling):
优点:
- 简单:短轮询是一种简单的实现方式,无需特殊的服务器支持。
- 适合低实时要求:对于实时要求不高的应用,短轮询可以满足需求。
- 不需要保持连接:客户端发送请求后,不需要保持与服务器的连接,可以降低服务器负担。
缺点:
- 频繁的请求:短轮询需要客户端频繁发送轮询请求,这可能导致网络流量增加和服务器负担加重。
- 实时性较差:因为客户端需要等待下一个轮询周期才能获取更新,所以实时性较差。
- 不适合大规模实时应用:对于大规模实时应用,短轮询可能导致服务器的负担过重。
所以,长轮询适合对实时性要求较高,但规模相对较小的应用,而短轮询适合对实时性要求不高,或者规模相对较小的应用。
但是对于大规模实时应用,长/短轮询还是不行的,通常需要采用其他技术。
WebSocket
WebSocket
使用 WebSocket
协议进行通信。WebSocket
连接以常规 HTTP
连接开始,通过 WebSocket
握手将其修改为 WebSocket
连接。握手以客户端发送带有特殊 UPGRADE
标头的 HTTP
请求开始。然后服务器接收请求,处理它,如果请求被接受,则切换到 WebSocket
协议。当这个握手完成时,双向通信是可能的。
通信过程
优缺点
优点:
-
实时双向通信:
WebSocket
允许客户端和服务器之间建立持久的双向通信通道,无需在每次通信时重新建立连接。 -
低延迟:由于
WebSocket
建立了持久的连接,它可以实现非常低的延迟,使应用程序能够在几乎实时的速度下进行通信。 -
减少网络流量:与短轮询和长轮询不同,
WebSocket
不需要客户端定期发起请求,从而减少了不必要的网络流量和服务器负载。 -
支持多种数据格式:
WebSocket
协议本身不限制数据格式,可以传输各种类型的数据,包括文本、二进制数据和JSON
等。 -
跨域通信:
WebSocket
允许跨域通信,因此可以在不同的域之间建立实时通信。 -
支持安全性:
WebSocket
可以通过TLS/SSL
进行加密,确保通信的安全性和隐私性。
缺点:
-
部署和维护复杂性:与传统的
HTTP
请求相比,WebSocket
需要更多的服务器端支持和管理,包括维护持久连接和处理连接中断等问题。 -
不适合所有应用:
WebSocket
最适合需要实时双向通信的应用,对于一些简单的应用,使用WebSocket
可能过于复杂。 -
防火墙和代理问题:一些网络环境中,防火墙和代理可能会阻止
WebSocket
连接,需要特殊配置或使用备选通信方法。 -
占用资源:保持大量
WebSocket
连接可能会占用服务器资源,特别是在大规模实时应用中。
所以WebSocket
特别适用于需要低延迟、双向通信和实时性的应用。但是对于一些要求不高的应用场景来说过于复杂,因此在选择WebSocket
时需要仔细考虑应用的需求和复杂性。
兼容性
Server Send Event(SSE)
Server-Sent Events(SSE),也称为EventSource
,是一种用于实现服务器向客户端单向推送数据的Web技术,也是基于HTTP
请求,响应时的Content-Type
为text/event-stream
。
通信过程
优缺点
优点:
-
实时性:
SSE
提供了实时性的服务器到客户端数据推送,使得它适用于需要即时更新的应用,如股票市场报价、天气预报、即时通知等。 -
简单性:
SSE
协议非常简单,易于使用和实现,不需要额外的库或协议,而且与标准的HTTP
服务器兼容。 -
长连接:
SSE
使用单个长连接,减少了与服务器的连接数,从而降低了服务器的负载。 -
自动重连:
SSE
客户端通常会自动尝试重新连接服务器,即使连接中断也可以恢复,提高了可靠性。 -
适合单向通信:
SSE
适合用于服务器向客户端的单向通信,客户端不需要发送数据到服务器。 -
使用纯文本传输:
SSE
基于纯文本,易于调试和理解,而且可读性强。
缺点:
-
单向通信:
SSE
是单向通信,只允许服务器向客户端推送数据,不支持客户端向服务器发送数据,因此不适合双向通信。 -
有限的浏览器支持:虽然大多数现代浏览器支持
SSE
,但不是所有浏览器都支持,这可能限制了应用的覆盖范围。需要在使用SSE
时检查浏览器的支持情况。 -
连接持续性:保持长连接可能会在某些情况下增加服务器和网络资源的占用,尤其是在大规模应用中。
-
难以实现广播:如果需要将消息广播给多个客户端,可能需要额外的逻辑来处理多个连接。
所以SSE
是一种适用于需要服务器向客户端单向实时推送数据的应用场景的简单而有效的技术。但是它不适合所有类型的实时通信需求,特别是双向通信。
比如咱们通常使用的 ChatGPT 、CI/CD构建平台的日志输出等都是使用的SSE
来推送数据的。
兼容性
总结
长轮询、短轮询、WebSocket
和Server-Sent Events(SSE)
都是用于实现实时通信的技术,但是要根据各个特点应用到各个场景:
-
长轮询(Long Polling):
- 应用场景:适用于需要实时通信但对实时性要求不是特别高的应用,如社交媒体更新、在线聊天等。
- 差异:服务器会保持客户端的连接,但不会立即响应,而是等待有新数据时才回复。这可以减少轮询请求的频率,但仍有一定延迟。
-
短轮询(Short Polling):
- 应用场景:适用于实时性要求不高的应用,如新闻网站、博客更新等。
- 差异:客户端会定期发送轮询请求,服务器会立即响应,但可能导致更频繁的网络流量和服务器负担。
-
WebSocket:
- 应用场景:适用于需要低延迟、双向通信的实时应用,如在线游戏、协作工具、在线拍卖等。
- 差异:
WebSocket
建立持久的双向连接,支持服务器向客户端和客户端向服务器的实时数据传输,具有较低的延迟和较高的性能。
-
Server-Sent Events (SSE):
- 应用场景:适用于需要服务器向客户端单向推送实时数据的应用,如股票市场报价、天气预报、即时通知等。
- 差异:
SSE
是基于HTTP
协议的单向通信,服务器向客户端推送数据,客户端不发送数据到服务器,适合单向通信需求,具有自动重连 和长连接的特点。
总结:长轮询和短轮询适用于实时性要求不高的应用,而WebSocket
和SSE
适用于需要实时、双向或单向推送的应用。WebSocket
更适合双向通信,而SSE
适合单向服务器到客户端的通知。