Rabbitmq PHP потребляют каждую секунду

Какова лучшая практика, чтобы получать данные из очереди каждую секунду через php? Я делаю это с помощью ajax-запроса, который вызывает php-скрипт каждую секунду. Там создается объект подключения и каждый раз объявляется очередь. Я пытался сохранить это после первого раза в переменной сеанса, но когда я вызываю скрипт PHP во второй раз, я не могу получить больше данных. Когда я отлаживаю объект канала, я вижу, что is_open имеет значение false:

  protected' is_open' => boolean false

Вот мой основной код теста php:

<?php


require_once __DIR__ . '/vendor/autoload.php';

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;



session_start(); # start session handling.

$id        = $_GET["uid"];
$connected = $_GET["connected"];

if (empty($id)) {
$id = 0;
}
$queue = 'CyOS EV Queue ' . $id;

$reset = $_GET["reset"];

if ($reset === "true") {
session_destroy();
$_SESSION = array();
echo "session destroyed";
var_dump($_SESSION);
exit;

}


$connection;
$channel;


if (!isset($_SESSION['coneccted'])) {

$_SESSION['coneccted'] = true;

$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');


$channel = $connection->channel();


$channel->queue_declare($queue, false, false, false, false, false);

$channel->queue_bind($queue, 'CyOS-EX');

$_SESSION['connection'] = $connection;
$_SESSION['channel']    = $channel;




} else {
echo "already connected \n\r";
$connection = $_SESSION['connection'];

$channel = $_SESSION['channel'];

var_dump($_SESSION);

}

$test = new AMQPMessage();

while ($i < 10) {

echo "try to get data from " . $queue . "\n\r";
$test = $channel->basic_get($queue, true);

$i++;
if (isset($test)) {
echo "received data";
break;

}
}
echo $test->body;

Когда я инициализирую соединение и канал каждый раз, когда вызываю скрипт, он работает.

0

Решение

Я предполагаю, что строки, о которых вы беспокоитесь, это:

$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->queue_declare($queue, false, false, false, false, false);
$channel->queue_bind($queue, 'CyOS-EX');

Давайте посмотрим, что здесь происходит:

  1. Подключитесь к серверу RabbitMQ. Это похоже на соединение с базой данных, или memcache, или любым другим внешним процессом, и должно происходить в каждом PHP-запросе. Вы не можете сохранить соединение в сеансе, потому что это не данные, это активный ресурс, который будет закрыт при выходе из PHP.
  2. Запросить канал по умолчанию для подключения. Это на самом деле только часть кода подключения, и она не должна занимать много времени или ресурсов.
  3. Объявите очередь. Это проверит, существует ли очередь, и если это произойдет, ничего не будет делать. С другой стороны, если вы знать очередь существует (потому что это постоянная очередь, созданная в интерфейсе администратора, или вы уверены, что другой процесс создал ее), вы можете пропустить эту строку.
  4. Привязать очередь к обмену. Это часть настройки очереди; если очередь не существует и еще не связана, в ней не будет ничего для потребления до тех пор, пока эта строка не запустится. Как и в предыдущем шаге, может быть пропущен, если вы знаете, что это произошло в другом месте.

Обычный способ избежать повторного подключения (шаги 1 и 2) состоит в том, чтобы потребитель работал в фоновом режиме, например запуск сценария PHP командной строки с помощью supervisord он работает непрерывно, обрабатывая сообщения по мере их поступления. Однако это не сработает, если вам нужно вернуть данные в браузер, как только они появятся в очереди.

Общие альтернативы опросу и созданию нового процесса PHP каждый раз включают:

  • Длинный опрос, при котором вызов AJAX ждет, пока ему что-то будет возвращено, а не возвращает пустой результат.
  • Потоковая передача ответа (отображение каждого результата из PHP в браузере по мере его получения, но не завершение процесса).
  • WebSockets (я не видел хорошей реализации в PHP, но одна может быть там).

Как я уже сказал, они не являются специфичными для RabbitMQ, но применяются в любое время, когда вы ожидаете, что что-то произойдет в базе данных, файле, удаленном сервисе и т. Д.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]