1

我正在尝试找到使用 PHP 向客户端发送数据的问题的解决方案。最大的问题是 - 我正在尝试做的是在使用 PHP 脚本的单个连接中继续发送数据。我确定还有其他方法,但目前我不知道如何解决这个问题。

我要做的是:客户端连接到 Web 服务器并保持连接打开,因此 TCP 连接“已建立”。他将每隔 X 秒继续发出例如 GET 请求,以保持此连接处于活动状态。

在某个事件的这个连接中,我想在没有他发出请求的情况下向客户端发送一些数据!所以这意味着事件是在服务器端触发的,而不是在客户端触发的。

由于我的客户端是 Arduino 模块,因此不可能使用任何 JavaScript 或任何客户端技术。我可以保持连接打开,但我需要使用 HTTP 将数据传递给客户端。

我在服务器上设置了一个数据库,当数据库内部发生变化时,PHP 会向客户端发送数据。

我试图在 PHP 脚本中循环运行 php flush();但这不是我想要的方式。

所以任何建议表示赞赏。谢谢你。

编辑:将是完美的解决方案也适用于 Windows 机器!

edit2:将有多个客户,而不仅仅是一个(例如数百个)

4

4 回答 4

1

只要您没有很多客户端,服务器端事件听起来就可以为您工作。 http://dsheiko.com/weblog/html5-and-server-sent-events

只需阅读您将拥有数百个客户端,在这种情况下,您可能不想使用 PHP,而是使用 node.js。

于 2012-12-26T22:25:23.663 回答
0

我认为您正在寻找的是 IPC - 进程间通信。在你的情况下,我会建议一个消息队列(或多个)

(在客户端)

  1. 打开连接到foo.php
  2. 收到新行时,对其进行处理。
  3. 如果连接超时,请重新打开它

(在服务器上 - foo.php

  1. 打开消息队列(您必须为每个用户注册一个消息队列!)
  2. 注册它,以便您bar.php了解它。
  3. 开始阻塞接收
  4. 收到消息后,发送您要发送的任何内容,FLUSH OUTPUT BUFFERS,返回2。
  5. 如果有任何超时,请返回2。

(在服务器上 - bar.php

  1. 当数据库发生变化时,向所有活动队列发送消息

这种方法存在一些问题:

  • 服务器端仅适用于 Linux / Unix(包括 Mac)
  • 消息队列数量有限
  • 您可能需要做一些家务,删除旧队列等。

好处:

  • 这是独立于应用程序的。消息队列是一种操作系统功能,因此您bar.php实际上可以说是一个 java 应用程序。
于 2012-12-26T23:02:56.237 回答
0

CRON 工作怎么样?

http://en.wikipedia.org/wiki/Cron

http://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/

我认为这可能是您项目的解决方案。如果我正确理解 CRON,你要做的就是以给定的时间间隔执行给定的脚本。所以这基本上就是你想要的,每 X 秒执行一次的脚本。在您的脚本中,您的函数与数据库一起使用。

于 2012-12-26T22:20:25.507 回答
0

好的,所以我想我找到了我想要的工作方式。flush() 不起作用的问题是我在刷新之前没有达到刷新缓冲区限制。此外,我正在使用 Nginx 服务器,并且禁用了 gzip(以防万一)。

我的绝对有效的测试代码如下所示:

<?
ob_implicit_flush(1);

for($i=0; $i<10; $i++){
  echo $i;

  //this is for the buffer achieve the minimum size in order to flush data
  echo str_repeat(' ',1024*64);

  sleep(1);
}
?>

在这里找到我的答案:PHP Flush that works... even in Nginx

如果它可以接受这样的输出,我将用我的 Arduinos 对其进行测试。感谢你的帮助。

于 2012-12-27T10:40:53.430 回答