我有执行 3 个任务的 ajax 请求:
- 保存模型 (DB)
- 发送电子邮件
- 给出成功或失败的消息。
因为这个任务太费时间了。用户最多可以等待 20 秒的响应(成功或失败消息)。如果用户关闭浏览器,它会停止用户当前进程的操作之一。
这是糟糕的用户体验。
我希望用户将他的数据提交给我的控制器,之后他将收到“成功或失败消息”。并且该过程将完全在服务器端,并且应该支持多会话。
我怎样才能做到这一点?
我有执行 3 个任务的 ajax 请求:
因为这个任务太费时间了。用户最多可以等待 20 秒的响应(成功或失败消息)。如果用户关闭浏览器,它会停止用户当前进程的操作之一。
这是糟糕的用户体验。
我希望用户将他的数据提交给我的控制器,之后他将收到“成功或失败消息”。并且该过程将完全在服务器端,并且应该支持多会话。
我怎样才能做到这一点?
@hakre 您提供的内容并没有减少用户等待响应的时间。
我找到了最好的解决方案: runactions extension for yii
这是一个扩展,可让您从控制器后台操作运行。有几种使用方法。最适合我的情况是这个
public function actionTimeConsumingProcess()
{
if (ERunActions::runBackground())
{
//do all the stuff that should work in background
mail->send()
}
else
{
//this code will be executed immediately
//echo 'Time-consuming process has been started'
//user->setFlash ...render ... redirect,
}
//User information
echo "Submit Success!"
}
它的工作,但没有 ajax 请求,当我提出 ajax 请求时,它由于某种原因无法工作。所以我用:
ERunActions::httpPOST($this->createAbsoluteUrl('Form/Submit'), array('to'=>'mail@domain.com', 'subject'=>'This is the subject'));
它的工作很棒,但它不是解决这个问题的理想解决方案。
关于 runactions 扩展的问题是它只适用于未经身份验证的用户,您可以使用yii backjob 扩展,但这将需要使用某种非阻塞会话存储,例如 CHttpDbSession。我仍在寻找正确的方法来做到这一点......我发现最好的选择之一是运行服务器后台作业:
/usr/bin/php -q longProcess.php > /dev/null 2>&1 &
但是,我仍然需要知道如何在 cmd 行中传递控制器和操作并允许 yii 实际使用它,例如
/usr/bin/php -q yii-index.php controller action > /dev/null 2>&1 &
更新:我发现最好的方法是使用 yii 控制台应用程序并将其作为后台作业运行。下面的链接帮助很大:
我现在使用这段代码,它运行良好:
exec("nohup /protected/yiic mycommand /dev/null 2>&1 &")