我正在开发一个由CakePHP框架构建的前端和基于Java的后端组成的系统。这两个生态系统之间的通信是通过从 CakePHP 控制器向 RabbitMQ 代理发送 JSON 消息来实现的。使用消息时,结果将发送回前端。现在,我需要使用消息并将结果从控制器推送到用户浏览器。对于PHP部分,我使用的是phpamqplib,但是在侦听新消息时需要有一个无限循环:
$channel->basic_consume('AMQP.COMMAND.OUTPUT.QUEUE',
'consumer',
false,
false,
false,
false,
array($this, 'processMessage'));
function shutdown($ch, $conn){
$ch->close();
$conn->close();
}
register_shutdown_function('shutdown', $channel, $conn);
while (count($channel->callbacks)) {
$read = array($conn->getSocket()); // add here other sockets that you need to attend
$write = null;
$except = null;
if (false === ($num_changed_streams = stream_select($read, $write, $except, 60))) {
/* Error handling */
} elseif ($num_changed_streams > 0) {
$channel->wait();
}
}
在我的控制器中,这会导致 Apache 服务器抛出错误,因为超过了 30 秒的最大执行时间。我真的需要这里的帮助。侦听新消息然后将结果推送到视图的最佳解决方案是什么?
谢谢
干杯。
我强烈建议将其转换为基于 AJAX 的基础架构,并重构您的代码以执行此操作:
- CakePHP 每 x 秒进行一次 AJAX 调用以加载页面
- AJAX URL 从队列中获取剩余元素,并输出它们
您的代码看起来不完整,所以我无法完全重构它,但您可以更改 AJAX URL 以执行以下操作:
if (count($channel->callbacks)) {
$read = array($conn->getSocket()); // add here other sockets that you need to attend
$write = null;
$except = null;
if (false === ($num_changed_streams = stream_select($read, $write, $except, 60))) {
/* Error handling */
}
}
并在完成后关闭通道。
如果您真的想使用推送,您的另一个选择是使用 Web 套接字。执行搜索,或者本教程可能会帮助您入门。