Как автоматически переподключить клиента на ratchetphp?

Я использую rachetphp для создания клиента для сервера API.
Но у меня есть проблема, когда мое соединение закрывается, независимо от причины, я не могу восстановить автоматически.

вот библиотека, которую я использую: https://github.com/ratchetphp/Pawl

<?php

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

$loop = React\EventLoop\Factory::create();
$connector = new Ratchet\Client\Connector($loop);

$connector('ws://127.0.0.1:9000', ['protocol1', 'subprotocol2'], ['Origin' => 'http://localhost'])
->then(function(Ratchet\Client\WebSocket $conn) {
$conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
echo "Received: {$msg}\n";
$conn->close();
});

$conn->on('close', function($code = null, $reason = null) {
echo "Connection closed ({$code} - {$reason})\n";
});

$conn->send('Hello World!');
}, function(\Exception $e) use ($loop) {
echo "Could not connect: {$e->getMessage()}\n";
$loop->stop();
});

$loop->run();

Я хотел бы попытаться переподключиться каждые секунды после закрытия соединения.
Есть идеи?

1

Решение

Идея проста, но требует некоторого рефакторинга. Мы должны поместить код переподключения в обработчик, который выполняется, когда соединение закрыто. Для этого мы передаем $app функционировать внутри себя.

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

$loop = React\EventLoop\Factory::create();
$connector = new Ratchet\Client\Connector($loop);

$app = function (Ratchet\Client\WebSocket $conn) use ($connector, $loop, &$app) {
$conn->on('message', function (\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
echo "Received: {$msg}\n";
$conn->close();
});

$conn->on('close', function ($code = null, $reason = null) use ($connector, $loop, $app) {
echo "Connection closed ({$code} - {$reason})\n";

//in 3 seconds the app will reconnect
$loop->addTimer(3, function () use ($connector, $loop, $app) {
connectToServer($connector, $loop, $app);
});
});

$conn->send('Hello World!');
};

function connectToServer($connector, $loop, $app)
{
$connector('ws://127.0.0.1:9000', ['protocol1', 'subprotocol2'], ['Origin' => 'http://localhost'])
->then($app, function (\Exception $e) use ($loop) {
echo "Could not connect: {$e->getMessage()}\n";
$loop->stop();
});
}

connectToServer($connector, $loop, $app);

$loop->run();

Идея заключается в том, что когда соединение получает close событие, которое мы делаем переподключение, используя connectToServer функция:

$conn->on('close', function ($code = null, $reason = null) use ($connector, $loop, $app) {
echo "Connection closed ({$code} - {$reason})\n";

//in 3 seconds the app will reconnect
$loop->addTimer(3, function () use ($connector, $loop, $app) {
connectToServer($connector, $loop, $app);
});
});
5

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

Если у вас есть pnctl (http://php.net/manual/en/book.pcntl.php), вы можете просто изменить обработчик ‘close’ на этот:

$conn->on('close', function($code = null, $reason = null) {
echo "Connection closed ({$code} - {$reason})\n";

// restart myself
global $argv;
pcntl_exec($_SERVER['_'], $argv);
exit();

});

Для меня это было проще, потому что я еще не извлек $ loop и $ connector, я просто использую

\Ratchet\Client\connect($ws_url, [], $headers)
->then(function ($conn) {
echo "connected\n";
...

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

function restartMyself() {
global $argv;
pcntl_exec($_SERVER['_'], $argv);
exit();
}
0

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