voxy/thruway-bundle

WebSockets (WAMP2) 集成于 Symfony2

安装次数: 119,224

依赖关系: 1

建议者: 0

安全: 0

星星: 97

关注者: 16

分支: 47

开放问题: 29

类型:symfony-bundle

0.4.2 2019-07-04 15:04 UTC

This package is auto-updated.

Last update: 2024-09-19 08:05:35 UTC


README

这是一个为 Thruway 定制的 Symfony Bundle,Thruway 是 WAMP (Web 应用消息协议) 的 PHP 实现。

注意:该项目正在经历很多变化,因此 API 将会更改。

使用 Composer 快速入门

安装 Thruway Bundle

  $ composer require "voryx/thruway-bundle"

更新 AppKernel.php (使用 Symfony < 4)

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

配置

#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
      

使用 Symfony 4,请使用如下文件名: config/packages/voryx.yaml

如果您使用的是内存中的用户提供者,则需要将 thruway 添加到安全防火墙中,并设置 in_memory_user_provider

#app/config/security.yml

security: 
   firewalls:
        thruway:
            security: false	     

您还可以使用 thruway.resource 标记服务,任何注解都将被捕获

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

注意:将服务标记为 thruway.resource 将使其公开。

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

通过 WampCRA 使用 FOSUserBundle 进行身份验证

将密码编码器(对现有网站来说有点棘手)更改为 master wamp challenge

#app/config/security.yml

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

设置 voryx_thruway.user_provider 为 "fos_user.user_provider"

#app/config/config.yml

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

WAMP-CRA 服务已经配置好了,我们只需要向它添加一个标记,以便包安装它

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

自定义授权管理器

您可以为授权管理器设置自己的授权管理器,以检查用户(通过其 authid 识别)是否有权发布 | 订阅 | 调用 | 注册

创建您的授权管理器服务,继承 RouterModuleClient 并实现 RealmModuleInterface(请参阅 Thruway 文档以获取详细信息)

// 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;
    }
}

注册您的授权管理器服务

     my_authorization_manager:
        class: ACME\AppBundle\Security\MyAuthorizationManager

在 voryx_thruway 配置中插入您的服务名称

#app/config/config.yml

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

重新启动 Thruway 服务器;现在它将在发布 | 订阅 | 调用 | 注册时检查授权。记住,在尝试订阅主题(或其他任何操作)时捕获错误,因为它现在可能被拒绝,并且这将作为错误返回。

用法

注册 RPC

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

调用 RPC

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

订阅

     use Voryx\ThruwayBundle\Annotation\Subscribe;

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

发布

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

它使用 Symfony Serializer,因此可以序列化和反序列化实体

    
    use Voryx\ThruwayBundle\Annotation\Register;

    /**
     *
     * @Register("com.example.addrpc", serializerEnableMaxDepthChecks=true)
     *
     */
    public function addAction(Post $post)
    {
        //Do something to $post

        return $post;
    }

启动 Thruway 进程

您可以在没有任何额外配置的情况下启动默认的 Thruway 工作进程(路由器和客户端工作进程)。

$ nohup php app/console thruway:process start &

默认情况下,路由器在 ws://127.0.0.1:8080 上启动

工作进程

Thruway Bundle 将为路由器和每个定义的工作进程启动一个单独的进程。如果您没有定义任何工作进程,所有标记的调用和订阅都将启动在 default 工作进程中。

将应用程序分解成多个工作进程的主要方法有两种。

  1. 使用 RegisterSubscribe 注解上的 worker 属性。以下 RPC 将添加到 posts 工作进程中。

      use Voryx\ThruwayBundle\Annotation\Register;
    
      /**
      * @Register("com.example.addrpc", serializerEnableMaxDepthChecks=true, worker="posts")
      */
      public function addAction(Post $post)
  2. 在类上使用 @Worker 注解。以下注解将创建一个名为 chat 的工作进程,它可以有最多 5 个实例。

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

如果工作进程以除 SIGTERM 之外的任何方式关闭,它将自动重启。

更多命令

查看正在运行的过程(工作进程)列表
$ php app/console thruway:process status
停止一个进程,例如 default
$ php app/console thruway:process stop default
启动一个进程,例如 default
$ php app/console thruway:process start default

JavaScript 客户端

对于客户端,您可以使用 AutobahnJS 或其他任何 WAMPv2 兼容客户端。

以下是一些示例

Symfony 4 快速入门

composer create-project symfony/skeleton my_project
cd my_project
composer require symfony/expression-language
composer require symfony/annotations-pack
composer require voryx/thruway-bundle:dev-master

创建配置文件 config/packages/my_project.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.

创建控制器 src/Controller/TestController.php

<?php
namespace App\Controller;

use Voryx\ThruwayBundle\Annotation\Register;

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

测试 RPC 是否配置正确 bin/console thruway:debug

 URI             Type Worker  File                                                  Method    
 com.example.add RPC  default /my_project/src/Controller/TestController.php         addAction 

对于我们所创建的 RPC 的更多调试信息: bin/console thruway:debug com.example.add

启动所有服务: bin/console thruway:process start

RPC com.example.add 现在可以在连接到 ws://127.0.0.1:8081 且 realm 为 realm1 的任何 WAMP 客户端上使用。