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

时间:2010-06-25 15:01:51

标签: 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..."

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

5 个答案:

答案 0 :(得分:5)

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

所以你被迫使用手头的工具,这意味着客户端需要询问服务器是否有任何新数据 - 轮询。轮询分为两种:间隔轮询长轮询。当您按时间间隔轮询时,您只需每隔 n 秒向服务器发出请求数据的请求。如果没有新的数据要返回,这是相当健谈的(请原谅双关语)。这就是人们在说“民意调查”时所想到的。

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

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

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


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

答案 1 :(得分:3)

如果某些浏览器无法使用它,那么

WebSockets可能会有所帮助。

如果你想在JavaScript中使用它,除了间隔轮询之外别无选择。

答案 2 :(得分:2)

您需要的是ajax push or reverse ajax。 有很多基于ajax的框架支持推送。在Java中,例如nextapp echo2,或者你也可以给ape project一个镜头。

答案 3 :(得分:2)

选项

  • Long-Polling :在数据到达之前保持请求处于打开状态。接收数据并关闭连接。打开新连接以再次接收数据。为了扩展,您需要为所有通信提供非阻塞IO)。这种方法最容易实现。如果您的服务器没有很多并发性,您甚至可以使用阻塞I / O.
  • HTTP-Streaming :接收数据时请勿关闭连接。为了使其能够跨浏览器工作,你必须做一些“黑客攻击”才能使它在所有浏览器中都能正常工作。
  • XMPP over BOSH 为此您使用XMPP服务器并将其与一些BOSH(XMPP over HTTP)一起使用。例如,Prosody是一个支持BOSH的简单XMPP服务器。接下来,您可以使用优秀的strophe.js库编写客户端。
  • Websockets :我想这将是未来,但目前浏览器支持还不足以真正用于所有浏览器。
  • Server-Sent Events :也非常酷的html5功能。在我看来,这个协议比websockets更简单。目前还没有得到所有majar浏览器的广泛支持。
  • Flash :如果您愿意,也可以通过Flash进行通信。浏览器必须安装Flash插件,但大多数情况都是如此。

最好的方法是什么?

  1. 在我看来,长轮询是通过HTTP实现基于事件的消息传递的最简单/最好的方式。它绝对不是最快的替代品,但每个主流浏览器都支持它并且最容易实现。
  2. 我认为Websockets将是最好的技术(未来),但尚未在浏览器中广泛采用。
  3. 尽管以上所有技术都非常好。他们都有利有弊。

答案 4 :(得分:0)

如果使用JavaScript完成,除了ping服务器之外没有其他任何方法。你唯一的选择是大力优化请求,避免无用地问“问题”。