Search code examples
phpsocketsclientreactphp

How to reconnect a client automatically on reactphp?


I'm using reactphp to create a client for an api server. But i have a problem, when my connection close, whatever the reason, i can't reconnect automatically.

It doesn't work:

$this->loop = \React\EventLoop\Factory::create();
$host = config('app.reactphp_receiver_host');
$port = config('app.reactphp_receiver_port');

$this->connector = new \React\Socket\Connector($this->loop);
$this->connector
     ->connect(sprintf('%s:%s', $host, $port))
     ->then(
           function (\React\Socket\ConnectionInterface $conn)
           {
              $conn->on('data', function($data)
              {

              });

              $conn->on('close', function()
              {
                   echo "close\n";
                   $this->loop->addTimer(4.0, function () {
                   $this->connector
                        ->connect('127.0.0.1:8061')
                        ->then( function (\Exception $e)
                        { 
                            echo $e;
                        });
                        });
               });
            });

$this->loop->run();

Exception is empty.


Solution

  • Hey ReactPHP team member here. Promise's then method accepts two callables. The first for when the operation is successful and the second for when an error occurs. Looks like you're mixing both in your example. My suggestion would be to use something like this where you capture errors and successes, but also can reconnect infinitely:

    $this->loop = \React\EventLoop\Factory::create();
    
    $this->connector = new \React\Socket\Connector($this->loop);
    
    function connect()
    {
      $host = config('app.reactphp_receiver_host');
      $port = config('app.reactphp_receiver_port');
      $this->connector
        ->connect(sprintf('%s:%s', $host, $port))
        ->then(
          function (\React\Socket\ConnectionInterface $conn) { 
            $conn->on('data', function($data) {
            });
            $conn->on('close', function() {
              echo "close\n";
              $this->loop->addTimer(4.0, function () {
                $this->connect();
              });
          }, function ($error) {
            echo (string)$error; // Replace with your way of handling errrors
          }
        );
    }
    
    $this->loop->run();