Php 在具有会话的web应用程序中处理耗时长的ajax调用
我非常想重新考虑一下我在web应用程序中实现的处理很长进程的方法 问题 我有一个用javascript编写的web应用程序,它通过API与服务器通信。此应用程序有一些“批量操作”,需要花费大量时间来执行。我希望以一种安全的方式执行它们,确保服务器不会超时,并向用户提供丰富的反馈,以便用户知道发生了什么 通常的方法 正如我在研究中所看到的,推荐的方法是在服务器中启动一个后台进程,让它在某个地方写下运行情况,这样您就可以请求检查它并向用户提供反馈。由于Im在后端使用php,因此该方法大致如下所述: 添加一些必要条件 由于我正在开发一个开源项目(WordPress插件),我希望它能在各种情况和环境下工作。我不想添加服务器端需求,而且据我所知,后台处理方法可能无法在几个共享托管解决方案中工作 我希望它能够开箱即用,在(几乎)任何具有典型WordPress支持的服务器上运行,即使它最终成为一个稍微慢一点的解决方案 我的方法 我们的想法是以一种方式打破这个过程,它将通过许多小请求以增量方式运行 因此,当浏览器第一次发送运行流程的请求时,它只会运行其中的一小步,并返回有用的信息以向用户提供一些反馈。然后浏览器执行另一个请求,并重复该请求,直到服务器通知该过程已完成 为了做到这一点,我将把这个对象存储在一个会话中,因此第一个请求将给我一个id,下面的请求将把这个id发送给服务器,以便它操作同一个对象 以下是一个概念性示例:Php 在具有会话的web应用程序中处理耗时长的ajax调用,php,web,timeout,single-page-application,background-process,Php,Web,Timeout,Single Page Application,Background Process,我非常想重新考虑一下我在web应用程序中实现的处理很长进程的方法 问题 我有一个用javascript编写的web应用程序,它通过API与服务器通信。此应用程序有一些“批量操作”,需要花费大量时间来执行。我希望以一种安全的方式执行它们,确保服务器不会超时,并向用户提供丰富的反馈,以便用户知道发生了什么 通常的方法 正如我在研究中所看到的,推荐的方法是在服务器中启动一个后台进程,让它在某个地方写下运行情况,这样您就可以请求检查它并向用户提供反馈。由于Im在后端使用php,因此该方法大致如下所述:
class LongProcess {
function __construct() {
$this->id = uniqid();
$_SESSION[$this->id] = $this;
$this->step = 1;
$this->total = 100;
}
function run() {
// do stuff based on the step you are in
$this->step = $this->step + 10;
if ($this->step >= $this->total)
return -1;
return $this->step;
}
}
function ajax_callback() {
session_start();
if (!isset($_POST['id']) || empty($_POST['id'])) {
$object = new LongProcess();
} else {
$object = $_SESSION[$_POST['id']];
}
$step = $object->run();
echo json_encode([
'id' => $object->id,
'step' => $return,
'total' => $object->total
]);
}
有了它,我可以让我的客户机递归地发送请求,并在收到响应时更新对用户的反馈
function recursively_ajax(session_id)
{
$.ajax({
type:"POST",
async:false, // set async false to wait for previous response
url: "xxx-ajax.php",
dataType:"json",
data:{
action: 'bulk_edit',
id: session_id
},
success: function(data)
{
updateFeedback(data);
if(data.step != -1){
recursively_ajax(data.id);
} else {
updateFeedback('finish');
}
}
});
}
$('#button').click(function() {
recursively_ajax();
});
当然,这只是一个概念证明,我甚至没有在实际代码中使用jQuery。这只是为了表达这个想法
请注意,存储在会话中的这个对象应该是一个非常轻量级的对象。任何正在处理的实际数据都应该存储在数据库或文件系统中,并且只在对象中引用它,以便它知道在哪里查找内容
一个典型的例子是处理一个大的CSV文件。文件将存储在文件系统中,对象将存储一个指向最后处理的行的指针,以便知道下一个请求从何处开始
该对象还可能返回一个更详细的日志,描述所做的一切并报告错误,以便用户完全了解所做的事情
我认为最好的界面是一个带有“查看详细信息”按钮的进度条,它可以打开一个包含详细日志的文本区域
这有意义吗?
所以现在我问。看起来怎么样?这是一个可行的方法吗
有没有更好的方法来做到这一点并确保它在非常有限的服务器上工作?您的方法有几个缺点:
在这两种情况下,我都不会将会话用作存储。将任务及其状态保存在数据库中,并使用一些锁定系统来确保只有一个进程可以修改一个任务的数据。这将比使用会话更加健壮和灵活。感谢您的所有输入。我只想在这里记录我得到的一些非常好的答案 一些名为Woocommerce的WordPress插件已经合并了来自“WP后台处理”库的代码,该库不再是Mantain,而是通过一些重要的改进实现了Cron方法。请参阅此博客帖子: 真正的图书馆就住在这里: 虽然这是一个特定于WordPress的库,但我认为这种方法适用于任何情况 对于WordPress,还有一个名为Action Scheduler的库,它不仅可以在后台处理tun进程,还允许您对它们进行调度。值得一看:
您的描述非常笼统,因此很难给出建议。例如,是否有必要