5

I need to publish messages from php script, I can publish a single message fine. But now I need to publish different messages in loop, can't find proper way how to do it, here is what I tried:

$counter = 0;
$closure = function (\Thruway\ClientSession $session) use ($connection, &$counter) {
//$counter will be always 5
$session->publish('com.example.hello', ['Hello, world from PHP!!! '.$counter], [], ["acknowledge" => true])->then(
    function () use ($connection) {
        $connection->close(); //You must close the connection or this will hang
        echo "Publish Acknowledged!\n";
    },
        function ($error) {
        // publish failed
            echo "Publish Error {$error}\n";
        }
    );
};

while($counter<5){

    $connection->on('open', $closure);

    $counter++;
}
$connection->open();

Here I want to publish $counter value to subscribers but the value is always 5, 1.Is there a way that I open connection before loop and then in loop I publish messages 2.How to access to $session->publish() from loop ?

Thanks!

dave101ua
  • 159
  • 1
  • 2
  • 11
  • Wouldn't `$connection->on('open' ...)` only run once? I don't know Thruway but it's quite likely that the 'open' event is only emitted once. That's why you only send one message regardless of the loop. – marekful Jul 13 '15 at 08:00
  • now I put $connection->open(); inside loop and it works as I need , but is it ok that I open connection every time ? In general I have a deamon which runs as : while(true){ ... } and publish messages there. – dave101ua Jul 13 '15 at 08:22
  • As per their [docs](https://github.com/voryx/Thruway), it seems you need to register and call a remote procedure to send data. ($session->register() and $session->call()) – marekful Jul 13 '15 at 08:29
  • I thought of that already, thing is that I can use $session->call() inisde this closure function only which runs only when I do $connection->open() – dave101ua Jul 13 '15 at 08:50

1 Answers1

5

There are a couple different ways to accomplish this. Most simply:

$client = new \Thruway\Peer\Client('realm1');
$client->setAttemptRetry(false);
$client->addTransportProvider(new \Thruway\Transport\PawlTransportProvider('ws://127.0.0.1:9090'));

$client->on('open', function (\Thruway\ClientSession $clientSession) {
    for ($i = 0; $i < 5; $i++) {
        $clientSession->publish('com.example.hello', ['Hello #' . $i]);
    }
    $clientSession->close();
});

$client->start();

There is nothing wrong with making many short connections to the router. If you are running in a daemon process though, it would probably make more sense to setup something that just uses the same client connection and then use the react loop to manage the loop instead of while(1):

$loop = \React\EventLoop\Factory::create();

$client = new \Thruway\Peer\Client('realm1', $loop);
$client->addTransportProvider(new \Thruway\Transport\PawlTransportProvider('ws://127.0.0.1:9090'));

$loop->addPeriodicTimer(0.5, function () use ($client) {

    // The other stuff you want to do every half second goes here

    $session = $client->getSession();

    if ($session && ($session->getState() == \Thruway\ClientSession::STATE_UP)) {
        $session->publish('com.example.hello', ['Hello again']);
    }
});

$client->start();

Notice that the $loop is now being passed into the client constructor and also that I got rid of the line disabling automatic reconnect (so if there are network issues, your script will reconnect).

mbonneau
  • 627
  • 3
  • 8
  • Thanks for your answer. I tried both examples, 1st one runs fine but if I change loop to while(1) then it never publish message as $client->start(); is not called. Same thing with 2nd example. If I run it as is then it does not publish messages as $client->start(); is not called ( – dave101ua Jul 16 '15 at 11:55