我使用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();
我想尝试在连接关闭后每秒重新连接一次。 有什么想法吗?
答案 0 :(得分:5)
这个想法很简单但需要一些重构。我们必须将重新连接代码放在连接关闭时执行的处理程序中。为此,我们在self中传递$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);
});
});
答案 1 :(得分:0)
如果您安装了pnctl(http://php.net/manual/en/book.pcntl.php),则只需将“关闭”处理程序更改为此:
$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();
}