Chrome 处理长连接时遇到的一些问题

最近在原有的 Webit 基础上开发了一个基于 HTTP 协议和 RESTful API 的消息推送程序。程序采用 Comet 模式实现 Server Push。

既然是 HTTP 协议,我便写了一个简单的 Web 客户端用于测试。这里记录一下其间遇到的一些问题。

  1. 多个标签页之间的长连接相互阻塞,通过开发者工具可以看到连接在 Stalled 这一阶段等待了 20 秒。
  2. 长连接在多个标签页之间跳跃,导致消息推送混乱。

研究一番后,明白了如下事实:

  1. 无论是否声明使用缓存,Chrome 在发起请求之前都会固执地访问缓存。我尝试添加了多个 HTTP 头声明禁止使用缓存均已失败告终。
  2. Chrome 访问缓存时会对缓存加读写锁,所以在对同一个资源发起多个请求时,后续请求会被阻塞直至锁释放或者达到 20 秒的锁超时时间。
  3. Chrome 会在多个标签页之间共享长连接,这是因为 HTTP 请求是无状态的,而共享连接可以减轻服务器负荷。

对于第一、二个原因,可以通过在请求地址后添加随机查询参数(一般来说是时间戳)来解决。

对于第三个问题,我写的程序虽然基于 HTTP 协议,却并是非无状态的。如果我的程序需要通过浏览器正常访问,则必须修改消息推送协议以适应无状态的 HTTP 协议。我暂时不打算这么做。所以我修改了 Web 客户端,取消了两次请求之间的延迟时间,使其在上一个连接返回时立刻发起一个新的请求,这样可以尽量保证一个标签页总是占用着同一个长连接。虽然这种解决方案不适用于生产环境,用来测试应该是足够了。

还有一些题外话,之前新浪微博的私信功能也是通过 Comet 实现的,所以大概由于浏览器对于单个服务器连接数量的限制,打开多个微博页面时会有一部分页面收不到私信提示。昨天在研究问题时又去看了一下,至少在使用 Chrome 访问时已经改为使用 WebSocket 来实现了。

相关文章
没有评论

留下评论

电子邮件地址不会被公开。 必填项已用*标注