IM通信技术快速入门:短轮询、长轮询、SSE、WebSocket

网络 网络管理
客户端发送一个 HTTP GET 请求到服务器,请求的路径是 WebSocket 的路径(类似 ws://example.com/socket)。请求中包含一些特殊的头字段,如 Upgrade: websocket 和 Connection: Upgrade,以表明客户端希望升级连接为 WebSocket。

前言

• 哈啰,大家好,我是洛林,对Web端即时通讯技术熟悉的开发者来说,回顾整个网页端IM的底层通信技术发展,从短轮询、长轮询,到后来的SSE以及WebSocket,我们使用的技术越来越先进,使用门槛也越来越低,给大家带来的网页端体验也越来越好。

• 因此,我们很多时候没有必要盲目追求新技术,而是适合场景的技术才是最好的技术,掌握WebSocket这些主流新技术固然重要,但了解短轮询、长轮询等所谓的“老技术”仍然大有裨益,这就是我分享这篇技术的原因。

即时通讯

• 对于IM/消息推送这类即时通讯系统而言,系统的关键就是“实时通信”能力。所谓实时通信有以下两层含义:

1、客户端可以主动向服务端发送信息。
2、当服务端内容发生变化时,服务端可以实时通知客户端。

常用技术

• 客户端轮询:传统意义上的短轮询(Short Polling)

• 服务器端轮询:长轮询(Long Polling)

• 单向服务器推送:Server-Sent Events(SSE)

• 全双工通信:WebSocket

短轮询(Short Polling)

实现原理

• 客户端向服务器端发送一个请求,服务器返回数据,然后客户端根据服务器端返回的数据进行处理。

• 客户端继续向服务器端发送请求,继续重复以上的步骤。(为了减小服务端压力一般会采用定时轮询的方式)

短轮询通信过程短轮询通信过程

优点

• 实现简单,不需要额外开发,仅需要定时发起请求,解析响应即可。

缺点

• 不断的发起请求和关闭请求,性能损耗以及对服务端的压力较大,且HTTP请求本身本身比较耗费资源。

• 轮询间隔不好控制。如果实时性要求较高,短轮询是明显的短板,但如果设置太长,会导致消息延迟。

长轮询(Long Polling)

实现原理

• 客户端发送一个请求,服务器会hold住这个请求。

• 直到监听的内容有改变,才会返回数据,断开连接(或者在一定的时间内,请求还得不到返回,就会因为超时自动断开连接);

• 客户端继续发送请求,重复以上步骤。

长轮询通信过程长轮询通信过程

改进点

• 长轮询是基于短轮询上的改进版本:减少了客户端发起Http连接的开销,改成在服务器端主动地去判断关注的内容是否变化。

基于iframe的长轮询

• 基于iframe的长轮询是长轮询的另一种实现方案。

实现原理

• 在页面中嵌入一个iframe,地址指向轮询的服务器地址,然后在父页面中放置一个执行函数,比如execute(data);

• 当服务器有内容改变时,会向iframe发送一个脚本;

• 通过发送的脚本,主动执行父页面中的方法,达到推送的效果。

总结

• 基于iframe的长轮询底层还是长轮询技术,只是实现方式不同,而且在浏览器上会显示请求未加载完成,图标会不停旋转,简直是强迫症杀手,个人不是很推荐。

iframe长轮询iframe长轮询

Server-Sent Events(SSE)

• 上面介绍的短轮询和长轮询技术,服务器端是无法主动给客户端推送消息的,都是客户端主动去请求服务器端获取最新的数据。而SSE是一种可以主动从服务端推送消息的技术。

• SSE的本质其实就是一个HTTP的长连接,只不过它给客户端发送的不是一次性的数据包,而是一个stream流,格式为text/event-stream。所以客户端不会关闭连接,会一直等着服务器发过来的新的数据流。

实现原理

• 客户端向服务端发起HTTP长连接,服务端返回stream响应流。客户端收到stream响应流并不会关闭连接而是一直等待服务端发送新的数据流。

图片图片

SSE通信过程

浏览器对 SSE 的支持情况

图片浏览器对 SSE 的支持情况

SSE vs WebSocket

• SSE 使用 HTTP 协议,现有的服务器软件都支持。WebSocket 是一个独立协议。

• SSE 属于轻量级,使用简单;WebSocket 协议相对复杂。

• SSE 默认支持断线重连,WebSocket 需要自己实现。

• SSE 一般只用来传送文本,二进制数据需要编码后传送,WebSocket 默认支持传送二进制数据。

• SSE 支持自定义发送的消息类型。

总结

• 对于仅需要服务端向客户端推送数据的场景,我们可以考虑实现更加简单的 SSE 而不是直接使用 WebSocket。

WebSocket

• WebSocket 是一种网络传输协议,可在单个 TCP 连接上进行全双工通信,位于 OSI 模型的应用层。

• WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。客户端和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。

实现原理

• 客户端发送一个 HTTP GET 请求到服务器,请求的路径是 WebSocket 的路径(类似 ws://example.com/socket)。请求中包含一些特殊的头字段,如 Upgrade: websocket 和 Connection: Upgrade,以表明客户端希望升级连接为 WebSocket。

• 服务器收到这个请求后,会返回一个 HTTP 101 状态码(协议切换协议)。同样在响应头中包含 Upgrade: websocket 和 Connection: Upgrade,以及一些其他的 WebSocket 特定的头字段,例如 Sec-WebSocket-Accept,用于验证握手的合法性。

• 客户端和服务器之间的连接从普通的 HTTP 连接升级为 WebSocket 连接。之后,客户端和服务器之间的通信就变成了 WebSocket 帧的传输,而不再是普通的 HTTP 请求和响应,客户端和服务端相互进行通信。

图片WebSocket通信过程

优点

• 实时性:WebSocket 提供了双向通信,服务器可以主动向客户端推送数据,实现实时性非常高,适用于实时聊天、在线协作等应用。

• 减少网络延迟:与轮询和长轮询相比,WebSocket 可以显著减少网络延迟,因为不需要在每个请求之间建立和关闭连接。

• 较小的数据传输开销:WebSocket 的数据帧相比于 HTTP 请求报文较小,减少了在每个请求中传输的开销,特别适用于需要频繁通信的应用。

• 较低的服务器资源占用:由于 WebSocket 的长连接特性,服务器可以处理更多的并发连接,相较于短连接有更低的资源占用。

• 跨域通信:与一些其他跨域通信方法相比,WebSocket 更容易实现跨域通信。

缺点

• 连接状态保持:长时间保持连接可能会导致服务器和客户端都需要维护连接状态,可能增加一些负担。

• 不适用于所有场景:对于一些请求-响应模式较为简单的场景,WebSocket 的实时特性可能并不是必要的,使用 HTTP 请求可能更为合适。

• 复杂性:与传统的 HTTP 请求相比,WebSocket 的实现和管理可能稍显复杂,尤其是在处理连接状态、异常等方面。

总结

• 在本文中我们介绍了IM通信技术中的常用四种技术:短轮询、长轮询、SSE、WebSocket,使用时可以综合我们的实际场景选择合适的通信技术,在复杂的应用场景中,我们可能需要结合不同的技术满足不同的需求,下面是一些常见的考虑因素:

实时性要求

• 如果实时性要求较低,短轮询或长轮询可能足够;如果需要实时性较高,考虑使用SSE或WebSocket,若仅需要服务端推送,尽可能考虑SSE。

网络和服务器资源

• 短轮询和长轮询可能会产生较多的无效请求,增加带宽和服务器负担;SSE和WebSocket相对更高效。

个人简介

👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.

责任编辑:武晓燕 来源: Lorin 洛林
相关推荐

2013-03-15 10:57:13

AJAXDotNet

2011-05-18 13:28:46

jQueryPHPAJAX

2015-09-07 14:08:32

Java编程异步事件

2021-01-12 05:07:56

服务器

2022-07-14 08:36:28

NacosApollo长轮询

2017-08-24 11:54:43

Linux日志定时轮循机制

2020-07-04 10:41:32

MQTTSSE网络协议

2020-12-10 08:44:35

WebSocket轮询Comet

2023-01-27 23:31:08

数据长轮询长连接

2012-08-01 14:16:27

IBMdW

2016-09-22 20:26:09

负载均衡lvsDNS轮询

2022-07-15 19:57:18

Cadence轮询开源

2018-12-03 08:42:02

反向代理层DNS轮询架构

2021-08-28 09:04:54

死锁顺序锁轮询锁

2021-02-26 12:37:39

WebSocketOkHttp连接

2020-07-07 14:49:17

中断轮询数据包

2021-08-31 07:57:21

轮询锁多线编程Java

2021-03-22 16:10:10

手机内存技术

2018-06-06 11:01:25

HTTP长连接短连接

2023-02-08 08:32:41

轮询锁
点赞
收藏

51CTO技术栈公众号