在web开发当中,常用的服务器推技术主要是两种,长轮询和持久连接。
如果我们仔细观察现有的产品实现,会发现,大多都会选择长轮询,而不是持久连接。(webqq、人人IM、facebook IM、新浪微博等都是基于长轮询)。
在不考虑其他插件技术,如flash等的情况下,对长轮询和持久连接做一下对比如下:
长轮询 | 持久连接 | |
性能 | 重复建立连接,网络开销大。 | 不需要重复建立连接,开销小,但需要间隔发送比较小的心跳包。 |
浏览器兼容性 | jsonp和xhr都可以兼容所有浏览器。 | iframe流可以兼容所有浏览器。 |
网络兼容性 | 可以兼容任何透明代理,防火墙。 | 无法兼容某些透明代理、防火墙。 |
我今天主要说一下《网络兼容性》这方面。现在,透明代理和防火墙代理的应用非常普遍。由于实际网络中,大量不支持http1.1以及不兼容的拦截代理配置的情况下,
基于持久连接的服务推技术,就不能正确实现了。
如上图所示的透明代理存在的情况下,内网的用户浏览器端发起的持久连接,可能在透明代理等存在的情况下,错误地当做的常规的基于“请求-响应”的短连接请求。
这样,当服务器在发送完数据,并继续保持连接的情况下,透明代理可能不会及时或正确地将数据返回给用户的浏览器端。
例如,透明代理可能会将服务器的响应放到一块缓冲区当中,当服务器关闭连接时,代理再将数据一并返回。当发生这种问题的时候,轻者会造成消息延迟,重者会导致客户端一段时间内没有收到心跳,而导致产生超时而主动断开连接。
因此,在复杂网络情况下,基于持久连接的服务推技术很可能会失效。而基于长轮询的服务器推技术,由于实际上跟普通的http请求没有根本上的差异,因而可以更好的穿过这些透明的中间代理。我想这也是很多WEBIM应用大多采用长轮询而不是持久连接的理由之一吧。