有没有真正的基于HTTP的服务器推送?

19

我知道有一些方法可以模拟,如轮询(或长轮询),但是否有任何方式让服务器联系浏览器以推送信息?

无论是哪种轮询选项,在服务器上都会浪费资源,并且根据服务器的不同可能会导致服务器卡住(例如Apache和IIS)。

似乎很多网站都在使用长轮询来模拟基于服务器端的HTTP推送机制。难道没有将真正的推送协议内置到浏览器中更好吗?

有哪些服务器友好的选项可以用来向Web浏览器推送(模拟或其他方式)信息?

7个回答

31

我知道有一些方法可以模拟,例如轮询(或长轮询),但是有没有一种方法可以让服务器联系浏览器以推送信息?

连接必须首先由客户端与服务器建立。没有办法让服务器联系Web客户端。

任何一种轮询选项都会浪费服务器资源,并且根据服务器的不同,可能会锁定它(例如Apache和IIS)。

没错。 频繁轮询效率低下,这也是我们正在转向持久连接的"推"世界的原因之一。 WebSockets将成为此问题的最佳解决方案。 我在Pusher工作,我们提供托管的实时WebSocket解决方案,我们看到由社区推动这项技术的大规模应用,认为这是解决资源和实时通信问题的最佳方案。

看起来很多网站都在使用长轮询来模拟基于HTTP的服务器端推送机制。是否更好地在浏览器中内置真正的推送协议?

是的,这就是为什么现在有了WebSocket的原因。 HTTP解决方案对于Web浏览器而言,最终是一种hack,不能在不同浏览器之间始终以相同的方式工作。

还有哪些选项对服务器友好,可以向Web浏览器推送(虚假或其他)信息?

  • HTTP长轮询:连接保持打开状态,直到服务器有新信息。 注意:这与标准轮询不同,后者请求新信息可能完全是浪费时间。
  • HTTP流传输:这可能是你正在寻找的解决方案(回答HTTP问题)。使用此技术,连接保持打开状态,并且可以通过该现有连接从服务器向客户端推送新的信息,而不必像使用HTTP长轮询一样关闭并重新打开连接。
  • HTTP / 2服务器推送:另一种向客户端推送的标准化机制。这些被称为“推送响应”,浏览器可以缓存这些响应。
  • WebSockets:在Web浏览器(或任何Web客户端)内通过单个TCP连接进行全双工通信。

相关信息和资源:

  1. 您可以将服务器发送事件(EventSource API)视为HTTP长轮询和HTTP流传输的标准化。
  2. HTTP / 2服务器推送

0

正如其他人所说,在常规HTTP中,服务器无法在没有客户端请求的情况下联系客户端。

但是,如果您正在寻找用于推送通知的清洁解决方案,请查看Server-Sent Events。它是常规HTTP,并且与大多数支持HTTP 1.1的浏览器无缝配合使用。

SSE仅在单向(服务器->客户端)中起作用,这是“推送通知”的主要机制。对于客户端->服务器通信,您始终可以使用Ajax。我在Which technology for realtime communication for a web app?中总结了这一点。


0

嗯,不行。

您的浏览器不会监听传入连接。

您也不希望它能够这样做。我们已经有足够的漏洞了。


关于RIA呢?(指真正的RIA,如Flex、Silverlight和JavaFX,而不是模仿RIA行为的巨型浏览器JavaScript库) - Manius
他们怎么样?即使它们可以绑定到一个IP:端口并接受套接字连接(据我所知,它们不能),从外部也无法访问它们(前提是用户没有做一些愚蠢的事情,比如不使用防火墙)。试图支持这种荒谬行为将会是一场噩梦,对于一个愚蠢到这样做的公司/项目来说。 - Brian Roach
LCDS带来真正的推送消息,因为它使用Adobe的专有实时消息传输协议(RTMP)在自身和客户端之间创建一个恒定的连接...(LCDS只是其中一种方式,还有GraniteDS w/Flex、Red5和BlazeDS支持一种形式的推送) - Manius
是的,自1996年以来,您就可以使用Java applet完成相同的基本操作。那里没有真正的魔法,它们肯定不是内置于浏览器中的。使用JavaScript和长轮询(彗星)几乎是执行此类操作的事实标准,而且它只是纯粹的工作-无需插件或臃肿的Adobe软件。您需要偶尔重新连接的事实并不是很重要。 - Brian Roach
臃肿?撇开偏见(你在这一点上已经表明了),问题是关于“真正”的推送。 AJAX的东西并不总是“顺利运行”,速度要慢得多,并且不能进行“真正”的推送。真正的RIA客户端确实具有这种能力。贬低技术事实对任何人都没有好处。另外,我忘了提到WebORB支持Flex的RTMP。(“真正”的服务器推送。) - Manius
显示剩余6条评论

0
如果您正在使用像Adobe Flex这样的RIA技术,我相信"服务器推送"(AMF消息)的Flex版本将符合您对服务器推送的定义。
当然,您也可以使用原始的ajax轮询方法,但除非被迫,否则没有理由这样做。

0
你不需要“假造”任何东西。Flash有一个非常好的和完善的Socket对象,它工作得非常出色,你可以编写一个微小的Flash应用程序,与网页通信,因此你不必在Flash中做任何事情(如果你更喜欢用HTML构建页面)。当然,你需要一个服务器端的socket监听器,但这些也很容易组合起来。有很多在线文档介绍如何实现整个过程...这是我找到的第一个例子(没有仔细看,但看起来会很好用)。 http://www.giantflyingsaucer.com/blog/?p=205

我认为这并不能解决问题:Flash应用程序是客户端,连接到服务器,而不是反过来。问题所在是需要一种让服务器联系客户端的方法。 - ibid
嗯...在任何情况下,客户端都必须首先联系服务器。但是一旦连接成功,它将保持连接状态(只要用户在页面上),并继续从服务器接收通信。你想解决什么情况?用户必须在某个时刻到达网页,对吧?那就是客户端连接的时刻。并且在他们离开之前,套接字会保持打开状态(除非出现问题)。你希望实现什么样的效果?(意思是...你希望得到什么?) - Yevgeny Simkin
自1996年以来,您就可以使用Java小程序完成相同的事情。 它仍然不比长轮询(comet)更“推送”;唯一的区别是长轮询必须每隔一段时间重新连接一次。 - Brian Roach
@DrDredel 没错。Flash/Flex应用程序,更不用说Java和可能的Silverlight了。我不明白为什么Brian坚持认为,既然Java多年来都能做到这一点,Flash能做到这一点就没有意义。显然,“AJAX”反插件特别利益集团今晚表现得很出色。事实是,无论是谁打开连接(在这种情况下是Flash),它都是一个“真正”的服务器推送,并且是Flash。所以苹果可以把这个事实塞回去。 :) - Manius

0

我认为WebSockets(参见http://en.m.wikipedia.org/wiki/WebSocket)是真正的推送技术,所以答案是:这取决于浏览器。如果您需要广泛兼容性,则今天最好的选择是JavaScript库,它会选择在其运行的浏览器中可用的最佳协议(例如https://github.com/ffdead/jquery-graceful-websocket)。但是,您想要服务器友好型,并且支持多种协议并不友好。当前的技术水平是跨浏览器实现酷炫功能需要大量工程投入。


Websockets并不是通过HTTP进行操作的。这是其中一个主要的优势(没有HTTP开销)。 - steveax
有一个初始的HTTP握手。实际上与HTTP流媒体类似——尽管在Web浏览器中缓冲区(XHR.responseText)会变得非常大,最终连接将需要被中断并重新建立。 - leggetter

0
也许自提出这个问题以来,技术已经有所进步...我是在查找其他内容时发现了这个。
WebPush 在大多数浏览器中都可用,并且有几个推送通知提供者可以将信息从服务器发送到浏览器。除了 Safari 等少数浏览器外,人们可以开发处理程序,在通知到达时调用它们并在客户端浏览器上执行某些操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接