有什么方法可以将数据从Web服务器推送到浏览器?


134

我当然知道Ajax,但是Ajax的问题​​是浏览器应该经常轮询服务器以查找是否有新数据。这会增加服务器负载。

除了频繁轮询服务器之外,还有什么更好的方法(甚至使用Ajax)吗?


1
我不确定那里。为了使该应用程序在概念上更简单,我猜您可以在轮询请求的基础上实现传输层,从而从应用程序逻辑中消除轮询责任。也许有人甚至已经实施了这个?<strong>编辑</ strong>:显然,它被称为<a href=" en.wikipedia.org/wiki/Reverse_Ajax">反向 Ajax </a>和<a href =“ en.wikipedia.org/wiki/Comet_(编程</ strong >,但是到目前为止,您似乎必须自己实现它。一个JavaScript库,有人吗?
安德斯·桑德维格

1
@Rachel-实时更新,因此您可以查看其他人在做什么。适用于StackOverflow等网站,以及适用于Google协作的Web应用程序。
Itai Bar-Haim '08年

1
在2016年执行此类操作的任何人都可能会发现websocket是此类通信的更好选择。
阴影

Answers:



37

是的,它叫做Reverse AjaxComet。Comet基本上是总括性术语,用于表示打开长期HTTP请求以将数据实时推送到Web浏览器的不同方式。我建议使用StreamHub Push Server,它们有一些不错的演示,并且比其他任何服务器都更容易上手。查看《Comet和StreamHub入门指南》以获取快速介绍。您可以使用社区版,该社区版可免费下载,但仅限20个并发用户。仅提供支持就值得使用商业版本,此外,您还可以获得SSL以及Desktop .NET和Java客户端适配器。可通过Google网上论坛获得帮助,网上有很多教程,还有GWT Comet适配器


1
绝对可行,一旦您自己实现,您将意识到要做的事-重新连接,长轮询,流式iframe,跨浏览器支持,HTTPS ...
Corehpf

2
解释什么是彗星将有助于解决这个问题
凯文·蒙克

1
@Satir:添加了快速说明。其他答案具有指向Wikipedia文章的链接。
Nosrama

32

现在,您应该使用WebSockets。这是2011年的标准,允许使用HTTP发起连接,然后将其升级为基于双向客户端-服务器消息的通信。

您可以通过javascript轻松启动连接:

var ws = new WebSocket("ws://your.domain.com/somePathIfYouNeed?args=any");
ws.onmessage = function (evt) 
{
  var message = evt.data;
  //decode message (with JSON or something) and do the needed
};

服务器端处理取决于您的技术堆栈。



8
我完全同意...使用HTTP进行双向通信就像在REST调用中思考让Mario跳到乌龟壳上一样……这是疯狂。您不需要发出请求,也不需要等待响应,只需按下按钮即可。……您只是不需要。HTTP是一个文档协议。超文本传输​​协议。Ajax Push是一种非常复杂的方法,可以绕过HTTP来执行WebSocket的设计。别再傻了,而是使用正确的工具来完成这项工作。
尼克·斯蒂尔

您真的很喜欢椭圆,有时甚至是一种新的四点形式,我将其称为“椭圆”!
inbatman '19



5

我强烈建议您花一些时间在Comet上,但是我不知道您可以使用的实际实现或库。

对于Web应用程序的某种“呼叫中心控制面板”,其中涉及为实时Callcenter更新代理和呼叫队列状态,我们开发了一种内部解决方案,该解决方案可以工作,但与您可以使用的库相距甚远。

我们要做的是在与电话系统进行对话的服务器上实现一项小型服务,等待新事件并维护情况的照片。该服务提供了一个小型Web服务器。

我们的Web客户端通过HTTP连接到该Web服务器,并索要最后一张照片(以XML编码),将其显示,然后再次查找新照片。此时,Web服务器可以:

  • 返回新照片(如果有)
  • 阻止客户端几秒钟(在我们的设置中为30秒),等待事件发生并更改照片。如果此时未生成任何事件,它将返回同一张照片,仅允许连接保持活动状态,而不会使客户端超时。

这样,当客户端进行轮询时,它将在最多0到30秒内得到响应。如果已经生成了新事件,它将立即获取它),否则它将阻塞直到生成新事件。

它基本上是轮询,但是它有点聪明,不会使Web服务器过热。如果Comet不是您的答案,我相信可以使用相同的想法来实现,但是可以使用更广泛的AJAX或JSON编码以获得更好的结果。这是在AJAX时代之前设计的,因此还有很多改进的空间。

如果有人可以提供这种方法的实际轻量级实现,那就太好了!


5

Comet的一个有趣替代方法是在Flash中使用套接字。




2

还有其他方法。不知道它们在您的情况下是否“更好”。您可能有一个Java小程序,该Java小程序在页面加载时连接到服务器,并等待服务器发送内容。它的启动速度会慢很多,但会允许浏览器不频繁地从服务器接收数据,而不会进行轮询。


2

您可以在客户端使用Flash / Flex应用程序,在服务器端使用BlazeDS或LiveCycle。可以使用RTMP连接将数据推送到客户端。请注意,RTMP使用非标准端口。但是,如果端口被阻塞,您可以轻松地返回轮询。


2

通过使用持久的http连接,可以实现您的目标。

在Wikipedia上查看Comet文章,这是一个不错的起点。

您提供的信息不多,但是如果您正在考虑构建某种事件驱动的网站(a'la digg spy)或类似的东西,您可能会希望实现与之连接的隐藏IFRAME一个连接永不关闭的URL,然后您将脚本标记从服务器推送到客户端以执行更新。



1

打开与服务器的连接后,它可以保持打开状态,并且服务器可以推送内容很久以前我使用过的内容,multipart/x-mixed-replace但这在IE中不起作用。

我认为您可以通过轮询来做一些聪明的事情,通过不发送内容不变的标头,而保持连接打开,使它更像推送,但我从未做过。





By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.