GithubHelp home page GithubHelp logo

voryx / thruway Goto Github PK

View Code? Open in Web Editor NEW
670.0 670.0 116.0 1.16 MB

PHP Client and Router Library for Autobahn and WAMP (Web Application Messaging Protocol) for Real-Time Application Messaging

License: MIT License

PHP 99.70% HTML 0.23% Shell 0.07%

thruway's People

Contributors

adamlc avatar benfavre avatar binaek avatar cboden avatar darthf1 avatar davidwdan avatar ddelbondio avatar djkoza avatar eichie avatar ftrrtf avatar lpj145 avatar mbonneau avatar mikesoule avatar oanhnn avatar pantsel avatar pronskiy avatar wyrihaximus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

thruway's Issues

Uncaught Exception if address in use

Uncaught exception 'React\Socket\ConnectionException' with message 'Could not bind to tcp://0.0.0.0:9090: Address already in use' in thruway/vendor/react/socket/src/Server.php:29

I need support about Internal Client

I am working on a sample for Internal Client + Authentication model like the one below.
Now I need to retrieve a list of connected sessions and intercept the close event of a session from Internal Client.
I want to ask if there's any method to archive that task? I was thinking about saving that list in redis, but it means I would have to re-write Thruway\Peer\Router classes, because the needed variables are now private, we don't have access to them to extends.

<?php
/**
 * server.php
 */

require "../bootstrap.php";
require 'InternalClient.php';
require 'SimpleAuthProviderClient.php';

use Thruway\Peer\Router;
use Thruway\Transport\RatchetTransportProvider;
use React\EventLoop\Factory;
use Thruway\Manager\ManagerClient;
use Thruway\Transport\InternalClientTransportProvider;

$manager = new ManagerClient();
$loop = Factory::create();

$router = new Router($loop, $manager);
$router->addTransportProvider(new InternalClientTransportProvider($manager));

$internalTransportProvider = new InternalClientTransportProvider(new \InternalClient());
$router->addTransportProvider($internalTransportProvider);

$authMgr = new \Thruway\Authentication\AuthenticationManager();

$router->setAuthenticationManager($authMgr);
$router->addTransportProvider(new InternalClientTransportProvider($authMgr));

//Provide authentication for the realm: 'somerealm'
$authProvClient = new SimpleAuthProviderClient(["somerealm"]);
$router->addTransportProvider(new InternalClientTransportProvider($authProvClient));

$transportProvider = new RatchetTransportProvider("127.0.0.1", 9090);
$router->addTransportProvider($transportProvider);

$router->start();
<?php
/**
 * SimpleAuthProviderClient.php
 */
require "../bootstrap.php";

/**
 * Class SimpleAuthProviderClient
 */
class SimpleAuthProviderClient extends \Thruway\Authentication\AbstractAuthProviderClient
{

    /**
     * @return string
     */
    public function getMethodName()
    {
        return 'simplysimple';
    }

    /**
     * @param mixed $signature
     * @param null $extra
     * @return array
     */
    public function processAuthenticate($signature, $extra = null)
    {
        if ($signature == "letMeIn") {
            return ["SUCCESS"];
        } else {
            return ["FAILURE"];
        }

    }

}
<?php
/**
 * InternalClient.php
 */
require "../bootstrap.php";

/**
 * Class InternalClient
 */
class InternalClient extends Thruway\Peer\Client
{

    function __construct()
    {
        parent::__construct("somerealm");
    }

    /**
     * @param \Thruway\AbstractSession $session
     * @param \Thruway\Transport\TransportInterface $transport
     */
    public function onSessionStart($session, $transport)
    {
        echo "--------------- Hello from InternalClient ------------";
        $this->getCallee()->register($this->session, 'com.example.getphpversion', [$this, 'getPhpVersion']);
    }


    function start()
    {
    }

    /**
     * @return array
     */
    function getPhpVersion()
    {
        return [phpversion()];
    }
}

REGISTER messages, incompatible format with Crossbar

Hi there,

We have recently started using Crossbar, and Crossbar installs Thruway as the default when using PHP.

However, in the past week or so we think there has been a change. The change is resulting in a stack trace error. You can see the CLI output here - crossbario/crossbar#139

@oberstet looked into the issue and reproduced the error. He recommended we open an issue here. Here is what he said:

This seems to be a Thruway bug. Thruway sends REGISTER messages of the format: [64,83887244,[],"com.example.add2"]. This is wrong, the 3rd item should be a dict, not a list.

Is this something you can help with?

How to completely quiet the manager ?

use something like this:

$client->getManager()->setQuiet(true);

Will keep printing messages such as:

We have been welcomed...
2014-11-30T21:01:04.7211170 debug      [Thruway\Transport\PawlTransportProvider 82490] Received: [65,1631857669006655,1042148048]
2014-11-30T21:01:04.7213660 info       [Thruway\Role\Callee 82490] Setting registration_id
2014-11-30T21:01:04.7217170 debug      [Vinelab\Minion\Client 82490] Client onMessage: [Thruway\Message\RegisteredMessage]

Where to log messages

Hi!
I want to save into a database all messages. I dont really know the right or recommended way to handly this.

At this moment I created a custom router (extending the default router) that saves the messages in the "onMessage" method. In this method I check if the message type is Thruway\Message\PublishMessage and get the content the realm name.

Is that a nice way or there are a better one?

Thank you

Transport Implementations

There is not a clear delineation in transports and transport providers as to responsibilities (who sends the message to the peer - the transport or the provider?). Also, there are incompatibilities that make transports specific to the Router or the Client (take a look at onClose as an example).

Internal client interfacing with third party

Hello,
I started using Thruway in my project and came into an obstacle I can't overcome. I need to interface my internal client with asterisk through marcelog/pami, and have no idea how to start client method periodicaly.

I tried to use addPeriodicTimer method in onSessionStart in my client like:

    public function onSessionStart($session, $transport)
    {
        $this->pamiClient = new ClientImpl($this->pamiSettings);
        $this->pamiClient->registerEventListener([$this, 'processAsteriskEvent']);

        $this->pamiClient->open();
        $pamiClient = $this->pamiClient;

        $this->getLoop()->addPeriodicTimer(1, [$pamiClient, 'process']);
    }
    public function processAsteriskEvent(EventMessage $event)
    {
        $this->getPublisher()->publish($this->session, "com.pami.publish", [[
            'from' => 'asterisk', 
            'message' => $event->getName()
        ]], [], []);
    }

It is sort of working - with

app/console thruway:client:start -vvv

I can see that all events are published:

[2014-10-08 09:50:42] app.DEBUG: Broker onMessage for {"type":"internalClient","transportAddress":"internal"}: [16,2632594463974922,{},"com.pami.publish",[{"from":"asterisk","message":"FullyBooted"}]] [] []
[2014-10-08 09:50:42] app.DEBUG: processing publish message [] []
[2014-10-08 09:50:44] app.DEBUG: Broker onMessage for {"type":"internalClient","transportAddress":"internal"}: [16,2564349979401664,{},"com.pami.publish",[{"from":"asterisk","message":"PeerStatus"}]] [] []
[2014-10-08 09:50:44] app.DEBUG: processing publish message [] []
[2014-10-08 09:50:45] app.DEBUG: Broker onMessage for {"type":"internalClient","transportAddress":"internal"}: [16,5167210401435635,{},"com.pami.publish",[{"from":"asterisk","message":"PeerStatus"}]] [] []

But are unable to connect with router with my web application (angular-wamp). When I comment out addPeriodicTimer line in my client, two web clients are connecting to router and chatting happily. Is this a way to connect some event to session's event loop or create non-blocking event loop in client? I tried to create other loop in client:

$this->pamiLoop = \React\EventLoop\Factory::create()
$this->pamiLoop->addPeriodicTimer(....);
$this->pamiLoop->run();

but it behaves in the same way.

Can't interface Internal client with Autobahn JS

Hello! I have some trouble while trying to make an internal client talk with one on the browser via autobahn js.

That's my setup:

// ws.php
<?php
require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/wsclient.php';

use Thruway\Peer\Router;
use Thruway\Transport\RatchetTransportProvider;
use Thruway\Transport\InternalClientTransportProvider;

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

$router = new Router($loop);

$transportProvider = new RatchetTransportProvider("127.0.0.1", 9090);

$router->addTransportProvider($transportProvider);

$internalClientTransportProvider = new InternalClientTransportProvider(new ChatClient($loop));

$router->addTransportProvider($internalClientTransportProvider);

$router->start();

And the internal client:

//wsclient.php
<?php

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

use Thruway\Transport\TransportInterface;
use Thruway\Message\Message;

class ChatClient extends Thruway\Peer\Client {

    public function __construct($loop)
    {
        return parent::__construct("realm1", $loop);
    }

    public function onSessionStart($session, $transport)
    {
        echo "--------------- Hello from InternalClient ------------\n";
        $this->getCallee()->register($this->session, 'com.myapp.version', [$this, 'getPhpVersion']);
    }

    public function start()
    {
    }

    public function getPhpVersion()
    {
        return [phpversion()];
    }
}

Finally my autobahn client:

var connection = new autobahn.Connection({url: 'ws://127.0.0.1:9090/', realm: 'realm1'});

connection.onopen = function (session) {

    session.call('com.myapp.version').then(
        function (res) {
            console.log(res);
        }
    );
};

connection.open();

One time out of ten it, someways, works and I see the version logged on the console, the other nine times I got this error:

Uncaught InvalidAccessError: Failed to execute 'close' on 'WebSocket': The code must be either 1000, or between 3000 and 4999. 1002 is neither.

For what I know code 1002 stand for internal error in websocket but I see no error logged anywhere and the websocket just keep going.

The strange thing is that if I create a php client with Thruway, like this:

//testClient.php
<?php

use Thruway\ClientSession;
use Thruway\Connection;

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

$connection = new Connection(
     [
        "realm" => 'realm1',
        "onClose" => $onClose,
        "url" => 'ws://127.0.0.1:9090/',
     ]
);

$connection->on('open',function (ClientSession $session) {

    $session->call('com.myapp.version')->then(
        function ($res) {
            echo "Result: {$res}";
        }
    );
});

$connection->open();

it just works, all the times!

I tryed to inject the main $loop into my internal client as suggested in #37 but with no luck...
The fact that it sometimes works made my think about some race conditions that my happen, but even adding a timeout before calling the function on my javascript code didn't work...

Am I missing something? Any help or suggestion is appreciated.

Synchronous client?

I would like to publish to a topic in the php code that is run within an http request, and it would be great if I can just connect, publish and disconnect in a synchronous way. How would you do that?

REGISTER message: wrong type for options item

It seems, recent Thruway client sends messages like [64,83887244,[],"com.example.add2"], which has list instead of dict for options.

See Crossbar.io user reporting: crossbario/crossbar#139

Sidenote: Do you think it would make sense to adjust the Thruway app template in Crossbar.io for the following?

  1. add handler for WebSocket close (which prints the WebSocket close code / reason)
  2. not require "dev-master" versions of Thruway / Pawl, but "some stable version" (crossbario/crossbar#139)

If you think this would make sense: could you probably send a PHP dummy the changes required for 1+2? ;)

send publish in event subscribe

When two internal client subscribes to the same event, will be caused by two different functions. But if the first function is to publish the second function does not call.

Stable and more customizable server release estimation ?

Are there any estimations of when this could be near production-ready ? I'm in the process of migrating a 7000 concurrent users project from NodeJS to PHP and WAMP v2, though the server component is the most of our interest so I wanter to ask whether efforts are being put there as well ? I'll be happy to jump on the collaboration board but need guidance regarding the plan.

Creating custom serializer

Hello!

Do you plan to implement possibility to use custom serializer in RatchetTransportProvider.
I need to switch off JsonSerializer.

Call to a member function publish() on a non-object

Hello to everyone,

I'm playing with crossbar.io examples, and I got stuck when executing php hello example. The main script crashes when calling $connection->doEvents(1). I have checked crossbar.io installation and config.json, and they both are ok, and also tested NodeJs and Python examples succesfully ( windows 8 machine).

Has anyone seen this problem before?

Php main script

        while (true) {

            // PUBLISH an event
            $session->publish('com.example.oncounter', array($counter));
            echo "published to 'oncounter' with counter {$counter}\n";
            $counter++;

            // CALL a remote procedure
            $session->call('com.example.mul2', array($counter, 3))->then(
                function ($res) {
                    echo "mul2() called with result: {$res}\n";
                },
                function ($error) {
                    if ($error !== 'wamp.error.no_such_procedure') {
                        echo "call of mul2() failed: {$error}\n";
                    }
                }
            );

            // Tell the connection to process the events every second
            $connection->doEvents(1);
        }

Crossbar.io script execution

2014-10-06 22:04:58+0200 [Router 3644] Site starting on 8080
2014-10-06 22:04:58+0200 [Guest  7916] subscribed to topic 'onhello'procedure add2() registered
2014-10-06 22:04:58+0200 [Guest  7916] published to 'oncounter' with counter 0
2014-10-06 22:04:58+0200 [Guest  7916] close
2014-10-06 22:04:59+0200 [Guest  7916] Fatal error: Call to a member function publish() on a non-object in C:..\hello\vendor\voryx\thruway\src\Thruway\ClientSession.php on line 57 
2014-10-06 22:04:59+0200 [Guest  7916] PHP Fatal error:  Call to a member function publish() on a non-object in C:..\hello\vendor\voryx\thruway\src\Thruway\ClientSession.php on line 57

Exclude publisher

Hi in autobahn we can publish message with option "exclude_me". This option exclude the publisher from the receivers for publication. Why Thruway dont handle message when exclude_me is false ?

property does not exist

Thruway/Transport/RatchetTransport.php on line 46
"Workaround" (??):

    public function getTransportDetails()
    {
        $request = null;
        if (property_exists($this->conn, 'webSocket')) {
            if (property_exists($this->conn->webSocket, 'request')) {
                $request = $this->conn->webSocket->request;
            }
        }
        return array(
            "type" => "ratchet",
            "request" => $request
        );
    }

What is the current WAMPv2 support?

I've been watching this project for WAMPv2 work and I see a lot of comments to this effect but I'm not sure what ot make of it. Does Thruway already have essential WAMPv2 support? If so it would be very helpful if any words could be given as to the current state. I think that Thruway could get more traction if just a small effort was put into communication. As it currently stands it seems to me that mostly only the people who are developing it have any idea what it currently can do.

Standardize the way Thruway handles WAMP dictionary types

The handling of dictionary types in Thruway is not consistent throughout. (see #48 - also has been mentioned in other issues)

Currently, the JSON serializer uses json_decode($serializedData, true) to decode messages. The true option forces all objects to be decoded into associative arrays.

This works fine at the first level: [4,"some_auth",{}] changes the third item to be an empty array, and immediately before encoding, we cast it back to an object to force it to encode correctly.

However, empty objects inside other objects or array's are not able to handle being decoded as an array: [4,"some_auth",{"object_option":{}}] will change to [4,"some_auth",{"object_option":[]}] after being decoded and then re-encoded.

This causes compatibility problems. To address this, the JSON serializer needs to drop the true option. This will cause all objects, including empty objects, to be decoded as a stdClass, which will require using the object operator ($helloMessage->getDetails()->roles) to access options, details, argumentsKw and any other classes within arguments, options, argumentsKw and details.

The setters on Message objects will still accept associative arrays when setting, but will be cast into objects.

This could potentially break existing code.

Proxy for client

My current task is to simplify (hide) JS-client interface communication with internal clients to the router. My idea was for implementation of a proxy based on internal clients. Or create your own Realm.

It is interesting to know your opinion, the best way?

Invocation Error needs to be implemented

In a callee with an RPC that returns a promise. If Deferred::reject is called, the callee should send invocation error - which should cause the dealer to send a call error to the caller, which should reject the promise returned by Caller::call.

Authorization?

Ok, our users can now get authenticated into our thruway powered WAMP v2 server but... How do we control authorization? I don't want all users to be able to publish or subscribe to any topic, I would like to limit this depending on the role of the user. Is it possible? Are there any onSubcribe and onPublish events? If so, how can I access the logged in user data?

Question about SimpleWsServer

Hi!
Could you give some more info how to operate with wamp protocol on server side (I mean subscribe, unsubscribe and other methods). What I need to do to find out with it?

php vendor/voryx/thruway/Examples/SimpleWsServer.php

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.