Ajax 使用 Symfony Process 组件进行轮询
Ajax polling with Symfony Process component
我正在开始一项较长的 运行ning 任务,该任务 return 是关于 Symfony Process 组件的任务进度的增量输出。
其中一个示例展示了如何获取实时输出,另一个示例展示了如何运行 异步任务。
我想要实现的是将 getIncrementalOutput 的结果传递回 ajax 轮询函数,以便我可以实时更新前端。
似乎在任何一种情况下 process->start() 都阻塞了,因为我的 ajax 调用需要一分钟才能到达 return,到那时任务已经完成。
我想我正在尝试避免将进度写入数据库或文件并直接从 运行ning PHP 任务中获取输出。
不确定是否可能。
虽然我不完全明白你想创建什么,但我写过类似的东西,看看它可能会回答你的问题:
首先我创建了一个执行长运行任务的命令:
class GenerateCardBarcodesCommand extends Command
{
protected function configure()
{
$this
->setName('app:generate-card-barcodes')
->setDescription('Generate the customer cards with barcodes')
->addArgument('id', InputArgument::REQUIRED, 'id of the Loy/Card entity')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$id = $input->getArgument('id');
// generate stuff and put them in the database
}
}
在控制器中启动了流程,并且有一个 ajax 操作
class CardController extends Controller
{
public function newAction(Request $request)
{
// run command in background to start generating barcodes
// NOTE: unset DYLD_LIBRARY_PATH is a fix for MacOSX develop using MAMP.
// @see
$process = new Process(sprintf('unset DYLD_LIBRARY_PATH ; php ../../apps/spin/console spin:loy:generate-card-barcodes %d', $entity->getId()));
$process->start();
sleep(1); // wait for process to start
// check for errors and output them through flashbag
if (!$process->isRunning())
if (!$process->isSuccessful())
$this->get('session')->getFlashBag()->add('error', "Oops! The process fininished with an error:".$process->getErrorOutput());
// otherwise assume the process is still running. It's progress will be displayed on the card index
return $this->redirect($this->generateUrl('loy_card'));
}
public function ajaxCreateBarcodesAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $this->getEntity($id);
$count = (int)$em->getRepository('ExtendasSpinBundle:Loy\CustomerCard')->getCount($entity);
return new Response(floor($count / ($entity->getNoCards() / 100)));
}
}
// 在 twig 模板中检索 ajax,它只是一个从 0 到 100 的数字,用于 jquery ui 进度条。
{{ 'Processing'|反式 }}...
<script type="text/javascript">
$(function() {
function pollLatestResponse() {
$.get("{{ path('loy_card_ajax_generate_barcodes', {'id': entity[0].id}) }}").done(function (perc) {
if (perc == 100)
{
clearInterval(pollTimer);
$('#download-{{entity[0].id}}').show();
$('#progress-{{entity[0].id}}').hide();
}
else
{
$('#progress-{{entity[0].id}}').progressbar("value", parseInt(perc));
}
});
}
var pollTimer;
$(document).ready(function () {
$('#progress-{{entity[0].id}}').progressbar({"value": false});
pollTimer = setInterval(pollLatestResponse, 2000);
});
});
</script>
我正在开始一项较长的 运行ning 任务,该任务 return 是关于 Symfony Process 组件的任务进度的增量输出。
其中一个示例展示了如何获取实时输出,另一个示例展示了如何运行 异步任务。
我想要实现的是将 getIncrementalOutput 的结果传递回 ajax 轮询函数,以便我可以实时更新前端。
似乎在任何一种情况下 process->start() 都阻塞了,因为我的 ajax 调用需要一分钟才能到达 return,到那时任务已经完成。
我想我正在尝试避免将进度写入数据库或文件并直接从 运行ning PHP 任务中获取输出。
不确定是否可能。
虽然我不完全明白你想创建什么,但我写过类似的东西,看看它可能会回答你的问题:
首先我创建了一个执行长运行任务的命令:
class GenerateCardBarcodesCommand extends Command
{
protected function configure()
{
$this
->setName('app:generate-card-barcodes')
->setDescription('Generate the customer cards with barcodes')
->addArgument('id', InputArgument::REQUIRED, 'id of the Loy/Card entity')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$id = $input->getArgument('id');
// generate stuff and put them in the database
}
}
在控制器中启动了流程,并且有一个 ajax 操作
class CardController extends Controller
{
public function newAction(Request $request)
{
// run command in background to start generating barcodes
// NOTE: unset DYLD_LIBRARY_PATH is a fix for MacOSX develop using MAMP.
// @see
$process = new Process(sprintf('unset DYLD_LIBRARY_PATH ; php ../../apps/spin/console spin:loy:generate-card-barcodes %d', $entity->getId()));
$process->start();
sleep(1); // wait for process to start
// check for errors and output them through flashbag
if (!$process->isRunning())
if (!$process->isSuccessful())
$this->get('session')->getFlashBag()->add('error', "Oops! The process fininished with an error:".$process->getErrorOutput());
// otherwise assume the process is still running. It's progress will be displayed on the card index
return $this->redirect($this->generateUrl('loy_card'));
}
public function ajaxCreateBarcodesAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $this->getEntity($id);
$count = (int)$em->getRepository('ExtendasSpinBundle:Loy\CustomerCard')->getCount($entity);
return new Response(floor($count / ($entity->getNoCards() / 100)));
}
}
// 在 twig 模板中检索 ajax,它只是一个从 0 到 100 的数字,用于 jquery ui 进度条。 {{ 'Processing'|反式 }}...
<script type="text/javascript">
$(function() {
function pollLatestResponse() {
$.get("{{ path('loy_card_ajax_generate_barcodes', {'id': entity[0].id}) }}").done(function (perc) {
if (perc == 100)
{
clearInterval(pollTimer);
$('#download-{{entity[0].id}}').show();
$('#progress-{{entity[0].id}}').hide();
}
else
{
$('#progress-{{entity[0].id}}').progressbar("value", parseInt(perc));
}
});
}
var pollTimer;
$(document).ready(function () {
$('#progress-{{entity[0].id}}').progressbar({"value": false});
pollTimer = setInterval(pollLatestResponse, 2000);
});
});
</script>