2

我正在为我的网站制作通知系统。我希望登录的用户在收到通知时立即注意到。正如许多人所说,只有几种方法可以做到这一点。

一种是编写一些 javascript 代码来询问服务器“是否有任何新通知?” 在给定的时间间隔内。它被称为“轮询”(我应该是对的)。

另一个是“长轮询”或“彗星”。正如维基百科所说,长轮询类似于轮询。无需每次都询问新通知,当有新通知可用时,服务器将它们直接发送给客户端。

那么我如何在 PHP 中使用长轮询?(不需要完整的源代码,而是一种这样做的方式)它的架构/设计到底是什么?

4

4 回答 4

3

长轮询的基本思想是您发送一个请求,然后服务器不会响应或终止该请求,直到某些所需的条件。即服务器端不会通过发送响应来“完成”服务请求。您可以通过在服务器端循环执行来实现这一点。

想象一下,在每个循环中,您都执行数据库查询或任何必要的操作,以确定您需要的条件现在是否为真。只有当它是你打破循环并将响应发送给客户端。当客户端收到响应时,它会立即重新发送“长轮询”请求,这样就不会错过下一个“通知”。

用于此的服务器端 PHP 代码的简化示例可能是:

// Set the loop to run 28 times, sleeping 2 seconds between each loop.
for($i = 1; $i < 29; $i++) {

    // find out if the condition is satisfied.
    // If YES, break the loop and send response     

    sleep(2);
}
// If nothing happened (the condition didn't satisfy) during the 28 loops,
// respond with a special response indicating no results. This helps avoiding
// problems of 'max_execution_time' reached. Still, the client should re-send the
// long-polling request even in this case.
于 2013-02-18T17:31:31.727 回答
1

我最近对聊天应用程序使用了长轮询。在做了一些研究并玩了一段时间之后,我会推荐一些东西。

1) 不要长时间轮询超过 20 秒。某些浏览器会超时。我通常将我的长轮询设置为运行大约 20 秒,然后在此时发回一个空响应。然后您可以使用 javascript 重新启动长轮询。

2)每隔一段时间,浏览器就会挂起。为了帮助添加第二级错误检查,我有一个 javascript 计时器运行 30 秒,如果 30 秒内没有响应,我放弃 ajax 调用并重新启动它。

3)如果您使用的是php,请确保您使用session_write_close()

4)如果您在 Jquery 中使用 ajax,您可能需要使用abort()

于 2013-02-18T18:48:12.937 回答
1

您可以使用(或研究)一些现有的实现,例如Ratchet。还有其他几个。

本质上,您需要避免让 apache 或 Web 服务器处理请求。就像使用 node.js 服务器一样,您可以从命令行启动 PHP 并使用服务器套接字函数来创建服务器并使用 socket_select 来处理通信。

通过保持循环处于活动状态,它可以在技术上通过 Web 服务器工作。但是,保持每个 HTTP 连接的 php 进程处于活动状态的内存开销通常太高。创建自己的服务器允许您在连接之间共享内存。

于 2013-02-18T17:37:00.897 回答
0

你可以在这里找到你的答案。更多细节在这里。并且您应该记住在使用$.ajaxSetup({ cache:false });jquery 时使用。

于 2013-02-19T16:11:00.613 回答