Отправка результатов из очереди RabbitMQ в интерфейс CakePHP

Я разрабатываю систему, состоящую из внешнего интерфейса, построенного на платформе CakePHP, и внутреннего интерфейса на основе Java. Связь между этими двумя экосистемами осуществляется путем отправки сообщений JSON от контроллера CakePHP брокеру RabbitMQ. Когда сообщение потребляется, результат отправляется обратно во внешний интерфейс. Теперь мне нужно обработать сообщение и отправить результат из контроллера в браузер пользователя. Для части 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 Server на выдачу ошибки из-за превышения максимального времени выполнения в 30 секунд. Мне действительно нужна помощь здесь. Какое лучшее решение для прослушивания новых сообщений, а затем для отображения результата в представлении?

Спасибо

Ваше здоровье.


person Nedo    schedule 03.06.2012    source источник


Ответы (1)


Я настоятельно рекомендую преобразовать это в инфраструктуру на основе AJAX и реорганизовать ваш код, чтобы сделать это:

  1. CakePHP делает вызов AJAX для загрузки страницы каждые x секунд
  2. URL-адрес AJAX получает оставшиеся элементы из очереди и выводит их

Ваш код не выглядит завершенным, поэтому я не могу его полностью реорганизовать, но вы можете изменить URL-адрес AJAX, чтобы сделать что-то вроде этого:

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 */
    }
}

и закройте канал, когда закончите.

Другой вариант, если вы действительно хотите использовать push, — использовать веб-сокеты. Выполните поиск или это руководство может помочь вам начать работу.

person Suman    schedule 26.06.2012