保持客户端浏览器了解事件(如新的聊天消息)的最佳方法是什么?

Eri*_*edo 4 javascript ajax

我认为,常见的方法是对服务器进行定期"ping",但我不喜欢它看起来太像

"Is there anything new? - No"
"Is there anything new? - No"
"Is there anything new? - No"
"Is there anything new? - No"
"Is there anyt..."
Run Code Online (Sandbox Code Playgroud)

我见过另一种方法,客户端要求新闻​​和服务器"保留"请求(例如,使用睡眠循环),直到有任何新的东西.这很酷,但我真的很想听听其他选择.

Bry*_*yle 5

遗憾的是,实际上没有任何跨浏览器机制可以将数据从服务器推送到浏览器.例如,早在1995年,Netscape发布了一种使用特殊内容类型的服务器推送技术 - multipart/x-mixed-replace,但据我所知,IE不支持它.WebSockets是一个新的,但支持刚刚问世.

因此,您不得不使用手头的工具,这意味着客户端需要询问服务器是否有任何新数据 - 轮询.轮询有两种类型:间隔轮询长轮询.当您按时间间隔轮询时,您只需每隔n秒向服务器发出请求数据的请求.如果没有新的数据要返回,这是相当健谈的(请原谅双关语).当你说"民意调查"时,这就是人们的想法.

另一个选项,长轮询,类似于客户端向服务器发出请求以查看是否有新数据.但在这种情况下,服务器在有话要说之前不会发送响应.在这种情况下,客户端会在不确定的时间内挂起响应.当客户端最终获得响应时,它会解析响应并立即发出另一个请求,该请求将一直保持挂起,直到有数据.

这两种轮询方法都消耗了大量的HTTP开销,但是如果你想使用XHR,那么这是实现它的唯一方法.

关于长轮询的警告:当使用长轮询时,确保所有XHR都异步运行非常重要,否则您将看到浏览器的UI线程锁定.


如果你对使用AJAX不感兴趣,那么你总是可以使用经过试验和测试的IFRAME-that-never-finish-loading.在这种情况下,您有一个带有聊天记录的IFRAME和另一个包含您的消息区域的IFRAME.在这种情况下,服务器根本不会关闭包含聊天日志的IFRAME的连接.相反,它只是将聊天消息推送到正文中.