在服务器事件发生时从服务器发送到客户端的通知

2022-08-31 00:13:44

我如何使用PHP将消息从服务器发送到客户端,避免无关的Ajax调用。

这个想法是这样的:

  1. 用户:Alice 进行更改,该更改将发送到服务器。

  2. 然后,服务器检查哪些用户不是最新的,如果没有,则调用一些代码将与更改相关的信息发送给 Bob(在本例中不是最新的)。

如何向鲍勃发送消息?


答案 1

可以使用服务器发送事件

这些是经常被过度查看的websockets的表亲,重量更轻,并且是单向的。它们基本上允许客户端等待来自服务器的消息(然后您可以通过其他通道(如AJAX)响应该消息)

示例客户端代码:

var source = new EventSource('/newFile');

source.addEventListener('message', function(e) {
  // Use AJAX and pull new file here
}, false);

不幸的是,似乎(当然)没有IE支持。可以使用 EventSource HQ 等库来支持跨浏览器服务器发送的事件。它将抽象出需要处理魔鬼的浏览器。


答案 2

你正在寻找的是(现在)非常普遍的东西,有时被称为“实时网络”。它能够让服务器端代码在发生时将内容实时推送到连接的客户端。

这是通过一些由最新浏览器(和服务器)支持的新机制以及一些其他机制来实现的,这些机制并不是真正设计用于这样做的,但可以用作“黑客”来使其工作。

你必须明白的第一件事是,你所要求的(服务器将消息“推送”到客户端)不是网络(或者至少是http)打算如何(或更好,曾经)工作。经典的Web是无状态的,请求 - 响应,半双工:客户端启动通信,打开与服务器的连接,服务器提供某些东西,然后连接关闭。过去,服务器无法向Web客户端发送消息:客户端(即您的浏览器)应该支持反向模型(提供它侦听的端点),从而有效地成为服务器。

这或多或少是像WebSockets这样的新标准所提供的(另一个值得一提的标准是服务器发送事件(SSE);然而,它的支持甚至比WebSockets更稀缺,它们似乎比发送单个消息更倾向于“流”内容)。

与HTTP不同,WebSocket提供全双工通信(任何一方都可以启动它),这就是您正在寻找的。WebSocket协议的正确版本(某些浏览器中存在较旧的错误实现)在Firefox 6,Safari 6,Google Chrome 14,Opera 12.10和Internet Explorer 10中实现。

那么,如果您的浏览器不支持WebSockets怎么办?你必须使用我之前提到的那些“技巧”。这些“伎俩”属于Push技术的不规则

特别是,一种常见的技术是长轮询。顾名思义,它不是“推”;长轮询是轮询,即“拉”技术,但它允许模拟推送机制。对于长轮询,客户端从服务器请求信息与在正常 AJAX 调用中完全相同,只是它以慢得多的频率发出其 HTTP/S 请求(轮询)。

连接后,服务器(您的服务器,您的API:servlet,HTTP处理程序,REST控制器等等!它通常与为标准AJAX调用提供支持的机制相同)如果已经有可用的更新,则发送一些信息;如果没有新内容,它不会发送空响应,而是保持请求打开状态并等待响应信息变为可用。

您有一个“传统”客户端发起的请求,但该请求被置于“暂停”状态,直到服务器想要与您通信为止。一旦有东西,服务器就会向客户端发送响应(通过HTTP通道,仍然打开!),完成打开的HTTP请求。

可以使用其他技术(例如使用插件提供的套接字 - Silverlight,Java小程序,Flash..),但是为了利用它们,您需要正确的客户端(浏览器/插件组合)。

当然,您可以自己实现所有这些内容。我鼓励你尝试作为一项学习练习

对于你的生产代码,你最好使用一个封装所有这些概念和技术的库,比如SignalR(用于 ASP.NET),Ratchet(用于PHP),Signal.IO(用于node.js),Faye(用于Ruby)。其中一些库将实现多种技术,根据客户端选择最佳技术,自动回退到其他技术。他们真的给你省去了很多麻烦!


推荐