2017 © Pedro Peláez
 

symfony-bundle thruway-bundle

WebSockets (WAMP2) integration for Symfony2

image

voryx/thruway-bundle

WebSockets (WAMP2) integration for Symfony2

  • Friday, March 9, 2018
  • by davidwdan
  • Repository
  • 15 Watchers
  • 85 Stars
  • 56,320 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 37 Forks
  • 22 Open issues
  • 11 Versions
  • 10 % Grown

The README.md

ThruwayBundle

This a Symfony Bundle for Thruway, which is a php implementation of WAMP (Web Application Messaging Protocol)., (*1)

Note: This project is still undergoing a lot of changes, so the API will change., (*2)

Quick Start with Composer

Install the Thruway Bundle, (*3)

  $ composer require "voryx/thruway-bundle"

Update AppKernel.php (when using Symfony < 4), (*4)

$bundles = array(
    // ...
    new Voryx\ThruwayBundle\VoryxThruwayBundle(),
    // ...
);

Configuration

#app/config/config.yml

voryx_thruway:
    realm: 'realm1'
    url: 'ws://127.0.0.1:8081' #The url that the clients will use to connect to the router
    router:
        ip: '127.0.0.1'  # the ip that the router should start on
        port: '8080'  # public facing port.  If authentication is enabled, this port will be protected
        trusted_port: '8081' # Bypasses all authentication.  Use this for trusted clients.
#        authentication: false # true will load the AuthenticationManager
    locations:
        bundles: ["AppBundle"]
#        files:
#            - "Acme\\DemoBundle\\Controller\\DemoController"
#
# For symfony 4, this bundle will automatically scan for annotated worker files in the src/Controller folder

With Symfony 4 use a filename like: config/packages/voryx.yaml, (*5)

If you are using the in-memory user provider, you'll need to add a thruway to the security firewall and set the in_memory_user_provider., (*6)

#app/config/security.yml

security: 
   firewalls:
        thruway:
            security: false      

You can also tag services with thruway.resource and any annotation will get picked up, (*7)

<service id="some.service" class="Acme\Bundle\SomeService">
    <tag name="thruway.resource"/>
</service>

Note: tagging a service as thruway.resource will make it public., (*8)

services:
    App\Worker\:
        resource: '../src/Worker'
        tags: ['thruway.resource']

Authentication with FOSUserBundle via WampCRA

Change the Password Encoder (tricky on existing sites) to master wamp challenge, (*9)

#app/config/security.yml

security:
    ...
    encoders:
        FOS\UserBundle\Model\UserInterface:
            algorithm:            pbkdf2
            hash_algorithm:       sha256
            encode_as_base64:     true
            iterations:           1000
            key_length:           32

set voryx_thruway.user_provider to "fos_user.user_provider", (*10)

#app/config/config.yml

voryx_thruway:
    user_provider: 'fos_user.user_provider.username' #fos_user.user_provider.username_email login with email

The WAMP-CRA service is already configured, we just need to add a tag to it to have the bundle install it:, (*11)

    wamp_cra_auth:
        class: Thruway\Authentication\WampCraAuthProvider
        parent: voryx.thruway.wamp.cra.auth.client
        tags:
            - { name: thruway.internal_client }

Custom Authorization Manager

You can set your own Authorization Manager in order to check if a user (identified by its authid) is allowed to publish | subscribe | call | register, (*12)

Create your Authorization Manager service, extending RouterModuleClient and implementing RealmModuleInterface (see the Thruway doc for details), (*13)

// src/ACME/AppBundle/Security/MyAuthorizationManager.php


use Thruway\Event\MessageEvent;
use Thruway\Event\NewRealmEvent;
use Thruway\Module\RealmModuleInterface;
use Thruway\Module\RouterModuleClient;

class MyAuthorizationManager extends RouterModuleClient implements RealmModuleInterface
{
    /**
     * Listen for Router events.
     * Required to add the authorization module to the realm
     *
     * @return array
     */
    public static function getSubscribedEvents()
    {
        return [
            'new_realm' => ['handleNewRealm', 10]
        ];
    }

    /**
     * @param NewRealmEvent $newRealmEvent
     */
    public function handleNewRealm(NewRealmEvent $newRealmEvent)
    {
        $realm = $newRealmEvent->realm;

        if ($realm->getRealmName() === $this->getRealm()) {
            $realm->addModule($this);
        }
    }

    /**
     * @return array
     */
    public function getSubscribedRealmEvents()
    {
        return [
            'PublishMessageEvent'   => ['authorize', 100],
            'SubscribeMessageEvent' => ['authorize', 100],
            'RegisterMessageEvent'  => ['authorize', 100],
            'CallMessageEvent'      => ['authorize', 100],
        ];
    }

    /**
     * @param MessageEvent $msg
     * @return bool
     */
    public function authorize(MessageEvent $msg)
    {
        if ($msg->session->getAuthenticationDetails()->getAuthId() === 'username') {
            return true;
        }
        return false;
    }
}

Register your authorization manager service, (*14)

     my_authorization_manager:
        class: ACME\AppBundle\Security\MyAuthorizationManager

Insert your service name in the voryx_thruway config, (*15)

#app/config/config.yml

voryx_thruway:
    ...
        authorization: my_authorization_manager # insert the name of your custom authorizationManager
   ...

Restart the Thruway server; it will now check authorization upon publish | subscribe | call | register. Remember to catch error when you try to subscribe to a topic (or any other action) as it may now be denied and this will be returned as an error., (*16)

Usage

Register RPC

    use Voryx\ThruwayBundle\Annotation\Register;

    /**
     *
     * @Register("com.example.add")
     *
     */
    public function addAction($num1, $num2)
    {
        return $num1 + $num2;
    }

Call RPC

    public function call($value)
    {
        $client = $this->container->get('thruway.client');
        $client->call("com.myapp.add", [2, 3])->then(
            function ($res) {
                echo $res[0];
            }
        );
    }

Subscribe

     use Voryx\ThruwayBundle\Annotation\Subscribe;

    /**
     *
     * @Subscribe("com.example.subscribe")
     *
     */
    public function subscribe($value)
    {
        echo $value;
    }

Publish

    public function publish($value)
    {
        $client = $this->container->get('thruway.client');
        $client->publish("com.myapp.hello_pubsub", [$value]);
    }

It uses Symfony Serializer, so it can serialize and deserialize Entities, (*17)


use Voryx\ThruwayBundle\Annotation\Register; /** * * @Register("com.example.addrpc", serializerEnableMaxDepthChecks=true) * */ public function addAction(Post $post) { //Do something to $post return $post; }

Start the Thruway Process

You can start the default Thruway workers (router and client workers), without any additional configuration., (*18)

$ nohup php app/console thruway:process start &

By default, the router starts on ws://127.0.0.1:8080, (*19)

Workers

The Thruway bundle will start up a separate process for the router and each defined worker. If you haven't defined any workers, all of the annotated calls and subscriptions will be started within the default worker., (*20)

There are two main ways to break your application apart into multiple workers., (*21)

  1. Use the worker property on the Register and Subscribe annotations. The following RPC will be added to the posts worker., (*22)

      use Voryx\ThruwayBundle\Annotation\Register;
    
      /**
      * @Register("com.example.addrpc", serializerEnableMaxDepthChecks=true, worker="posts")
      */
      public function addAction(Post $post)
    
  2. Use the @Worker annotation on the class. The following annotation will create a worker called chat that can have a max of 5 instances., (*23)

      use Voryx\ThruwayBundle\Annotation\Worker;
    
      /**
      * @Worker("chat", maxProcesses="5")
      */
      class ChatController
    

If a worker is shut down with anything other than SIGTERM, it will automatically be restarted., (*24)

More Commands

To see a list of running processes (workers)
$ php app/console thruway:process status
Stop a process, i.e. default
$ php app/console thruway:process stop default
Start a process, i.e. default
$ php app/console thruway:process start default

Javascript Client

For the client, you can use AutobahnJS or any other WAMPv2 compatible client., (*25)

Here are some examples, (*26)

Symfony 4 Quick Start

composer create-project symfony/skeleton my_project

```BASH cd my_project, (*27)

```BASH
composer require symfony/expression-language

```BASH composer require symfony/annotations-pack, (*28)

```BASH
composer require voryx/thruway-bundle:dev-master

Create config/packages/my_project.yml with the following config:, (*29)

voryx_thruway:
    realm: 'realm1'
    url: 'ws://127.0.0.1:8081' #The url that the clients will use to connect to the router
    router:
        ip: '127.0.0.1'  # the ip that the router should start on
        port: '8080'  # public facing port.  If authentication is enabled, this port will be protected
        trusted_port: '8081' # Bypasses all authentication.  Use this for trusted clients.

Create the controller src/Controller/TestController.php, (*30)

<?php
namespace App\Controller;

use Voryx\ThruwayBundle\Annotation\Register;

class TestController
{
    /**
     * @Register("com.example.add")
     */
    public function addAction($num1, $num2)
    {
        return $num1 + $num2;
    }
}

Test to see if the RPC has been configured correctly bin/console thruway:debug BASH URI Type Worker File Method com.example.add RPC default /my_project/src/Controller/TestController.php addAction For more debug info for the RPC we created: bin/console thruway:debug com.example.add, (*31)

Start everything: bin/console thruway:process start, (*32)

The RPC com.example.add is now available to any WAMP client connected to ws://127.0.0.1:8081 on realm1., (*33)

The Versions

09/03 2018

dev-master

9999999-dev

WebSockets (WAMP2) integration for Symfony2

  Sources   Download

MIT

The Requires

 

The Development Requires

by Matt Bonneau
by David Dan

symfony sockets wamp websockets wamp2 autobahn

02/01 2018

0.3.1

0.3.1.0

WebSockets (WAMP2) integration for Symfony2

  Sources   Download

MIT

The Requires

 

The Development Requires

by Matt Bonneau
by David Dan

symfony sockets wamp websockets wamp2 autobahn

01/01 2018

0.3.0

0.3.0.0

WebSockets (WAMP2) integration for Symfony2

  Sources   Download

MIT

The Requires

 

The Development Requires

by Matt Bonneau
by David Dan

symfony sockets wamp websockets wamp2 autobahn

06/06 2017

dev-symfony_serializer

dev-symfony_serializer

WebSockets (WAMP2) integration for Symfony2

  Sources   Download

MIT

The Requires

 

The Development Requires

by Matt Bonneau
by David Dan

symfony sockets wamp websockets wamp2 autobahn

10/04 2017

0.2.0

0.2.0.0

WebSockets (WAMP2) integration for Symfony2

  Sources   Download

MIT

The Requires

 

The Development Requires

by Matt Bonneau
by David Dan

symfony sockets wamp websockets wamp2 autobahn

16/02 2016

1.0.x-dev

1.0.9999999.9999999-dev

WebSockets (WAMP2) integration for Symfony2

  Sources   Download

MIT

The Requires

 

The Development Requires

by Matt Bonneau
by David Dan

symfony sockets wamp websockets wamp2 autobahn

04/12 2015

0.1.0

0.1.0.0

WebSockets (WAMP2) integration for Symfony2

  Sources   Download

MIT

The Requires

 

The Development Requires

by Matt Bonneau
by David Dan

symfony sockets wamp websockets wamp2 autobahn

24/08 2015

0.0.4

0.0.4.0

WebSockets (WAMP2) integration for Symfony2

  Sources   Download

MIT

The Requires

 

The Development Requires

by Matt Bonneau
by David Dan

symfony sockets wamp websockets wamp2 autobahn

26/05 2015

0.0.3

0.0.3.0

WebSockets (WAMP2) integration for Symfony2

  Sources   Download

MIT

The Requires

 

The Development Requires

by Matt Bonneau
by David Dan

symfony sockets wamp websockets wamp2 autobahn

06/03 2015

0.0.2

0.0.2.0

WebSockets (WAMP2) integration for Symfony2

  Sources   Download

MIT

The Requires

 

by Matt Bonneau
by David Dan

symfony sockets wamp websockets wamp2 autobahn

20/02 2015

0.0.1

0.0.1.0

WebSockets (WAMP2) integration for Symfony2

  Sources   Download

MIT

The Requires

 

by Matt Bonneau
by David Dan

symfony sockets wamp websockets wamp2 autobahn