voryx / Thruway

PHP Client and Router Library for Autobahn and WAMP (Web Application Messaging Protocol) for Real-Time Application Messaging
MIT License
674 stars 117 forks source link

Creating connection within RealmModuleInterface instance hangs on Starting Transport #265

Closed J7mbo closed 6 years ago

J7mbo commented 7 years ago

Very simply, I'm trying to have onSubscribe and be able to actually handle the broadcasting of data when I require, likely using LoopInterface::addPeriodicTimer. Regardless, when I try creating a connection within this RealmModuleInterface instance, it hangs on "Starting Transport". FTR, I'm doing this in a docker container.

class EventHandler implements RealmModuleInterface
{
    public function getSubscribedRealmEvents()
    {
        return [
            'SubscribeMessageEvent' => ['onSubscribe', 100]
        ];
    }

    public function onSubscribe(MessageEvent $event)
    {
        $connection = new \Thruway\Connection(
            [
                "realm" => 'realm1',
                "url"   => 'ws://127.0.0.1:1338'
            ]
        );

        $connection->on('open', function (\Thruway\ClientSession $session) use ($connection, $args) {
            echo 'OPENED' . PHP_EOL;
            $connection->close();
        });

        $connection->open();
    }
}

Then, when trying to subscribe with autobahn.js very simply (just a one line session.subscribe() call so omitted for brevity), it causes the hang:

Here's the debug output:

2017-09-05T19:17:46.6775250 notice     Changing PHP precision from 14 to 16
2017-09-05T19:17:46.6947200 debug      [Thruway\Peer\Router 53] New router created
2017-09-05T19:17:46.7108890 debug      [Thruway\RealmManager 53] Creating new realm "realm1"
2017-09-05T19:17:46.7250300 debug      [Thruway\RealmManager 53] Adding realm "realm1"
2017-09-05T19:17:46.7371540 info       [Thruway\Peer\Router 53] Starting router
2017-09-05T19:17:46.7865870 info       [Thruway\Transport\RatchetTransportProvider 53] Websocket listening on 0.0.0.0:1338
2017-09-05T19:17:46.7966940 info       [Thruway\Peer\Router 53] Starting loop
2017-09-05T19:17:53.0201350 debug      [Thruway\Transport\RatchetTransportProvider 53] RatchetTransportProvider::onOpen
2017-09-05T19:17:53.0462900 debug      [Thruway\Transport\RatchetTransportProvider 53] onMessage: ([1,"realm1",{"roles":{"caller":{"features":{"caller_identification":true,"progressive_call_results":true}},"callee":{"features":{"caller_identification":true,"pattern_based_registration":true,"shared_registration":true,"progressive_call_results":true,"registration_revocation":true}},"publisher":{"features":{"publisher_identification":true,"subscriber_blackwhite_listing":true,"publisher_exclusion":true}},"subscriber":{"features":{"publisher_identification":true,"pattern_based_subscription":true,"subscription_revocation":true}}}}])
2017-09-05T19:17:53.0555800 info       [Thruway\RealmManager 53] Got prehello...
2017-09-05T19:17:53.0700190 debug      [Thruway\Transport\RatchetTransportProvider 53] onMessage: ([32,6078804886125377,{},"my.topic"])
2017-09-05T19:17:53.0813680 info       [Thruway\Peer\Client 53] New client created
2017-09-05T19:17:53.0870680 info       [Thruway\Transport\PawlTransportProvider 53] Starting Transport

Also, here's my bootstrap code:

$loop = Factory::create();
$router = new \Thruway\Peer\Router($loop);
$transport = new \Thruway\Transport\RatchetTransportProvider('0.0.0.0', 1338);

$router->addTransportProvider($transport);
$router->getRealmManager()->getRealm('realm1')->addModule(new \Workshop\EventHandler($loop));
$router->start();

What am I doing wrong?

mbonneau commented 7 years ago

A couple of things:

You can implement what you are trying to do by extending Client:

class EventHandler extends Client implements RealmModuleInterface
{
    public function getSubscribedRealmEvents()
    {
        return [
            'SubscribeMessageEvent' => ['onSubscribe', 100]
        ];
    }

    public function onSubscribe(MessageEvent $event)
    {
        echo "Got subscribed event...\n";

        $clientSession = $this->getSession();
        if ($clientSession) {
            /** @var SubscribeMessage $subscribeMessage */
            $subscribeMessage = $event->message;

            $clientSession->publish(
                'some.topic',
                [$event->session->getSessionId() . ' just subscribed to ' . $subscribeMessage->getTopicName()]
            );
        }
    }
}

With the bootstrap:

$loop = Factory::create();
$router = new \Thruway\Peer\Router($loop);
$transport = new \Thruway\Transport\RatchetTransportProvider('0.0.0.0', 1338);

$router->addTransportProvider($transport);
$realmModule = new EventHandler('realm1', $loop);
$router->addInternalClient($realmModule);
$router->getRealmManager()->getRealm('realm1')->addModule($realmModule);
$router->start();

If you are looking to keep track of subscriptions, you may want to look at https://github.com/voryx/ThruwaySubscriptionMeta.