1

我希望一个 PHP 脚本等待另一个脚本执行期间发送的事件。

用户 A 和用户 B 都是我网站的访问者。当用户 A 访问 index.php 时,页面开始执行,但直到用户 B 也访问 index.php 才返回。(该页面仅在两个用户都连接到 Web 服务器时显示,例如:就像两个守卫通过同时转动钥匙打开保险箱。)

实现这一点的一种方法是让 index.php 暂停其执行,直到收到由其他用户访问 index.php 引起的通知。

为此,我查看了

  1. 自由事件;但它似乎不允许在信令期间发送“ID”或“字符串”。
  2. 来自梨的 Event_Dispatcher;但它在“脚本之间”不起作用。
  3. PHP共享内存函数;但似乎不能等到内存改变。
4

4 回答 4

3

您可能不希望 PHP 脚本完全暂停。用户会坐在那里以为页面冻结了。相反,我会使用 AJAX 将 USER-A 的状态保存在数据库中,然后使用 AJAX 再次检查 USER-B 是否也保存了他们的状态。想法是让 AJAX 在后台默默地检查 USER-B 的状态。当它确实检测到登录时,让您的回调函数对页面进行处理!

于 2011-02-04T03:22:25.577 回答
2

在“等待”请求(用户 A)的代码中,创建一个新的监听套接字(http://php.net/manual/en/sockets.examples.php)绑定到不会冲突的本地主机地址和端口与其他任何东西(例如,127.12.34.56 端口 7890)然后通过调用 socket_accept 等待连接。如果已经有一个请求在该状态等待,这将失败,否则它将在那里等待连接。

在您的“信号”请求(用户 B)中,创建一个新套接字,并连接到您的侦听套接字。等待用户 A 请求的 PHP 处理程序将立即从它被阻止的 socket_accept 调用返回,您可以继续。如果您需要在两者之间传递任何消息,您可以简单地从套接字读取和写入消息。

对于聊天室和显示服务器发送事件的通知页面等应用程序来说,这是一项非常常见的任务。与轮询方法相比,这种方法有一些优点,轮询方法不断调用睡眠并循环检查数据库或文件(或从 JavaScript 端循环向服务器发出许多请求):

- 它不会创建消耗资源和网络流量的不必要的 HTTP 请求或 DB 查询或 CPU 循环

-当触发事件发生时立即行动,没有任何延迟

- 它不依赖于数据库或文件

主要缺点是您的 PHP 必须有权打开套接字并连接到它们,而在共享主机环境中通常不是这种情况。

例如,请参阅https://gist.github.com/root9b/e1f0b82769296b06c079e53c7362bb94

于 2016-06-15T20:57:38.343 回答
1

使用睡眠和数据库怎么样?

客户端 1 登录,PHP 插入一个“等待条目”,然后以设定的时间间隔(可能使用 time_nanosleep)轮询数据库以获取已标记为“完成”的内容。
客户端 2 登录,PHP 更新“等待条目”以将其设置为“完成”。
客户 1 看到流程已完成,便愉快地继续前进。

如果您没有数据库,则可以使用简单的临时文件来完成。

于 2011-02-04T03:39:12.847 回答
0

您正在寻找守护进程,有一些信息如何创建它:

http://kevin.vanzonneveld.net/techblog/article/create_daemons_in_php/

于 2011-02-04T03:20:26.077 回答