Ajax长轮询与服务器推的长连接的区别是?

关注者
90
被浏览
11640
(本题之前有些答案都没看清题目……)

【读题】
——————————————————————

要搞清楚 AJAX 长轮询,首先要会用 AJAX(短)轮询 —— JS 让浏览器发起一个“询问”请求,服务器无论有无新数据,都立即响应(有就返回新数据,没有就返回一个表示“空”的自定义数据格式),一个 HTTP 连接结束,JS settimeout 一会儿再向同一URL 发起同样的请求,如此反复,故曰“(短)轮询”~

而长轮询的区别在于 —— 当没有新数据时,服务器端并不立即响应,而是用循环语句 + sleep(此处以 PHP 为例,总之是进程挂起一会儿)轮询数据源(内存数据库、硬盘数据库 或 远程服务器),在这个等待过程中,浏览器状态栏会显示“正在加载 xxx”、Web Debugger 网络选项卡中会显示这个请求处于 Pending 状态。服务器直到发现新数据时才给浏览器响应,而浏览器依然是得到响应后隔一段时间再发起同样的请求。

也就是说,“长轮询”长在每次轮询请求的响应时间长,其 HTTP 连接不是频繁断开、重连的,减少了 HTTP 连接“三次握手”的性能损耗。

——————————————————————

HTML 5 标准中的 Server-Send Event(简称 SSE)与长轮询的区别在于有更长时间的 HTTP 连接,谓之“长连接” —— 服务器发完了新数据也不断开连接,继续等待下一份新数据,除非超过了一定的时限(即自定义的最大连接空闲时长,浏览器可以超时重连)。

而一些答主提到的 Web Socket 连接不是基于 HTTP 传输的,它是一种 HTML 5 为 Web 定制的全双工通讯协议,没有“请求 - 响应”的概念,浏览器与服务器完全平等,连接一旦建立就一直开放,双方可随时向对方发送任意数据,没有推拉之分。

——————————————————————

由此可见,本答案从前到后阐述的4种 Web 消息通讯方式,其实时性越来越好,每次网络连接保持的时间也越来越长,以致对服务器并发性能的要求也水涨船高。因为通常,一个网络连接占用一个端口号,一个端口号对应一个服务进程,一个进程又要打开一个数据文件或数据库连接,但服务器操作系统运行时的最大端口号、最大进程数、最大文件打开数 等等又是有限的,超时重连的缓解作用也有限。

所以,要么缩小实时消息的应用范围(只服务必要的实时需求),要么为服务器集群扩容。但无论如何,服务器架构的整体优化一定紧跟业务规模的发展,甚至要尽早内部预研

而从浏览器兼容难度看 —— 短轮询/AJAX > 长轮询/Comet > 长连接/SSE > Web Socket,但 Web Socket 无法用现有前端技术模拟,而 SSE 已有成熟的 Polyfill(Yaffle/EventSource · GitHub)。