从服务器进程获取实时反馈[在PHP中]

时间:2014-04-13 20:07:45

标签: php ajax pthreads fork proc

要求:

我需要运行一个后台进程(根据用户请求),大约需要30到60秒才能完成。我想向用户提供一些状态反馈。 注意:Toly是对的,'背景'不是必需的。

什么工作:

此过程在此期间打印大约20条状态消息,我使用proc_open检索它们并使用fgets监听读取管道。我可以将这些消息保存到会话var中并使用时间戳(以帮助调试)我可以看到随着进程的进行会话数组被写入这些消息。

麻烦:

我的计划是使用ajax调用(每秒)轮询服务器以检索这些会话变量以便在DOM中显示。瓶颈似乎是服务器在仍在运行后台进程时无法为ajax请求提供服务。后台进程完成后,一切都会立即转储。据我所知,问题不在于输出缓冲,因为使用(调试)时间戳保存在每个进程消息中,表明服务器正在顺序写入会话变量,因此我知道proc_open和管道读取的方式是像我期待的那样工作。问题似乎是服务器在完成该过程之前无法向AJAX请求它​​的JSON对象;或者,更准确地说,完成了读取管道的循环。

明显的误解:

我认为向后台发送进程(使用&)可能会在这里给我一个解决方案。显然我不知道后台进程和分叉进程之间的区别。通过在后台运行流程获得的好处(如果有的话)在这种情况下似乎对我没有任何影响?

可能的解决方案:

  1. 我不希望用户启动运行此过程的进程 过程/场景很重,但如果我能做到的话 构建到这个解决方案,这将有助于重负载然后我会 喜欢这样做。
  2. 这是多线程(pthreads)还是a 多进程(fork)解决方案?
  3. 或者,我应该保存进程ID, 让我们用while(... fgets ..)语句轮询它然后 在服务器为ajax提供服务后回到进程 请求?
  4. 我想我可以运行假状态消息然后 结果在完成后返回时准确响应。 处理请求的时间不依赖于用户,因此 我的假时间可能非常准确。但是,我想 知道提供实时反馈的解决方案。

2 个答案:

答案 0 :(得分:3)

在google-ing有一天获得技术以获得您在此处描述的相同行为后,我为我的项目提出了一个简单的解决方案。

一些重要的理论: - session_start()和类似$ _SESSION [“x”] =“y”的集合将始终锁定会话文件。

案例场景: - A - process.php - 通过ajax调用 - B - get_session.php - 第二个ajax调用;

主要的问题是,即使你在一个正在通过AJAX运行的进程中设置一个$ _SESSION,它总是必须等待会话文件被解锁并且它将导致之间的同步这两个过程(A. + B.) - 两者同时完成!

因此,解决此问题并获得良好结果的最简单方法是在每个集合之后使用session_write_close()。 E.g:

%_SESSION["A"] = "B";
$_SESSION["x"] = "y";
session_write_close();

PS:最好的方法是拥有一组定制的功能来处理会话。

对不起加价。我刚刚创建了一个堆栈帐户。

答案 1 :(得分:0)

为什么你认为你需要后台程序?另外,你在哪里知道你需要一个?

一个普通的php脚本,有足够的超时设置,每一步都使用flush()函数,可以为你提供AJAX所需的输出。

更简单,因为您使用会话 - 对单独的处理程序的AJAX请求,只检查会话中的内容,以及是否有新的 - 将返回新的部分。< / p>

$_SESSION['progress'] = array();

内部process.php

$_SESSION['progress'][] = 'Done 5%';
// complete some commands
$_SESSION['progress'][] = 'Done 10%';

在ajax.php里面

if(count($_SESSION['progress']) > $_GET['laststep']) {
    // echo the new messages
}

在您的正常页面内

$.ajax('ajax.php', 'GET', 'laststep=1', success: function(data){ show(data);})

这样的事情应该有用。