ZeekDaGeek
ZeekDaGeek

Reputation: 21

I'm unable to cross communicate with ReactPHP's Pawl and Ratchet

I'm currently attempting to connect to two different socket servers. One of them is essentially an IRC connection, the other is an interface server that I've made myself. These two loops need to be able to communicate with each other, but I'm having difficulty actually sending a message from one connection to another.

Here's what I've been trying as a simplified way of injecting the message, the comments are not very confident because I'm honestly not sure where I'm going wrong:

<?php

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

    // EventLoop the way I understand it is designed to split up your loops and
    // run them one after another so you can kind of multithread, even though
    // it's just one step of the loop at a time.
    $loop = \React\EventLoop\Factory::create();

    // Verbose defintion of connectors mainly trying to just gain extra control
    // and so I could see how each thing was defined.
    $reactConnector = new \React\Socket\Connector($loop, [
        'dns' => '8.8.8.8',
        'timeout' => 10
    ]);

    $connector = new \Ratchet\Client\Connector($loop, $reactConnector);

    // Connect as a client to the development Socket server. This is all just
    // from the Pawl github essentially.
    // 
    // The connection is successful every time.
    $ws = $connector('ws://0.0.0.0:5069', [], ['Origin' => 'http://localhost']);
    ->then(function(Ratchet\Client\WebSocket $conn) {

        // Simple echo on message received for the test.
        $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
            echo "Received: {$msg}\n";
        });

        $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();
    });

    // Instead of including a second socket connector I decided to use a simple
    // timer and try to get it to use the client connection above to send
    // messages to the socket server.
    // 
    // The problem is here, I can't get the socket server to send a message
    // from outside of the ->then();
    $loop->addPeriodicTimer(1, function () use ($ws) {

        $ws->then(function (Ratchet\Client\WebSocket $conn) {
            $conn->send('Figured out?');
        });

    });

    $loop->run();

I'd really like to be able to send messages from one connection the the other through some sort of $ws->send('message');, but I can't for the life of me figure out how.

Upvotes: 1

Views: 956

Answers (1)

user1290173
user1290173

Reputation: 46

Ahhh Finally a question I can answer!! I spent most of yesterday working through my own Ratchet/Pawl client that had to have addPeriodicTimer loops to send content at periodic times. It took some poking around but I made it work by placing the $loop->addPeriodicTimer() call INSIDE of the connector block, after the ->then(function(Ratchet\Client\WebSocket $conn) part and before the $conn->on('message'...) calls. Also for the $loop->addPeriodicTimer calls make sure to add the use clause passing in the connection ... and make sure to add the use clause passing in the $loop to the connector.

<?php

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

    // EventLoop the way I understand it is designed to split up your loops and
    // run them one after another so you can kind of multithread, even though
    // it's just one step of the loop at a time.
    $loop = \React\EventLoop\Factory::create();

    // Verbose defintion of connectors mainly trying to just gain extra control
    // and so I could see how each thing was defined.
    $reactConnector = new \React\Socket\Connector($loop, [
        'dns' => '8.8.8.8',
        'timeout' => 10
    ]);

    $connector = new \Ratchet\Client\Connector($loop, $reactConnector);

    // Connect as a client to the development Socket server. This is all just
    // from the Pawl github essentially.
    // 
    // The connection is successful every time.
    $ws = $connector('ws://0.0.0.0:5069', [], ['Origin' => 'http://localhost']);
    ->then(function(Ratchet\Client\WebSocket $conn) use ( $loop ) {


    $loop->addPeriodicTimer(1, function () use ( $conn ) {

            $conn->send('Figured out?');

    });

        // Simple echo on message received for the test.
        $conn->on('message', function(\Ratchet\RFC6455\Messaging\MessageInterface $msg) use ($conn) {
            echo "Received: {$msg}\n";
        });

        $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();

Upvotes: 1

Related Questions