【问题标题】:How to reconnect a client automatically on ratchetphp?如何在 ratchetphp 上自动重新连接客户端?
【发布时间】:2017-08-27 23:03:53
【问题描述】:

我正在使用 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();

我想在连接关闭后每隔几秒尝试重新连接。 有什么想法吗?

【问题讨论】:

    标签: php sockets client wss reactphp


    【解决方案1】:

    如果您安装了 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();
    }
    

    【讨论】:

    • 如果您能详细说明您在此讨论的内容,我会很高兴,因为我一直无法获得公认的工作答案,并希望您的答案能够。但是php.net/manual/en/intro.pcntl.php 说“不应在 Web 服务器环境中启用流程控制,如果在 Web 服务器环境中使用任何流程控制功能,可能会出现意外结果。”,这让我感到害怕。
    • 这就是我说“如果你安装了它”的原因。如果您从网络服务器(apache mod_php 或 php-fpm)调用它,可能会导致坏事发生。如果您控制环境并知道它仅在 CLI 中使用,那么它就可以工作。
    • 我怀疑这是否是个好主意。详细说明他在做什么:他没有重新连接,他正在从低级别重新启动整个 php 进程。这意味着整个 php 启动正在重新启动,与真正的连接重新启动相比,它可能会对性能产生不良影响。这也意味着每个变量都被重置,这样你就失去了整个程序流程。当然只针对 CLI 脚本,apache 不会喜欢的
    【解决方案2】:

    这个想法很简单,但需要一些重构。我们必须将重新连接代码放在连接关闭时执行的处理程序中。为此,我们在 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);
        });
    });
    

    【讨论】:

    • 非常好!有了这个,我也可以在“错误”或“关闭”事件后重新连接。
    猜你喜欢
    • 2018-09-17
    • 1970-01-01
    • 2018-02-27
    • 1970-01-01
    • 2012-07-24
    • 2010-09-17
    • 2020-12-10
    • 2019-11-20
    • 2015-03-10
    相关资源
    最近更新 更多