voxy / thruway-bundle
WebSockets (WAMP2) 集成于 Symfony2
Requires
- php: >=5.6
- react/child-process: ~0.4
- symfony/event-dispatcher: ^2.7|^3.0|^4.0
- symfony/finder: ^2.7|^3.0|^4.0
- symfony/serializer: ^2.7|^3.0|^4.0
- thruway/pawl-transport: ^0.5.0
- voryx/thruway: ~0.5
Requires (Dev)
- doctrine/orm: ~2.1
- phpunit/phpunit: ~5.0
- symfony/symfony: ^2.7|^3.0|^4.0
- symfony/yaml: 2.*
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
工作进程中。
将应用程序分解成多个工作进程的主要方法有两种。
-
使用
Register
和Subscribe
注解上的worker
属性。以下 RPC 将添加到posts
工作进程中。use Voryx\ThruwayBundle\Annotation\Register; /** * @Register("com.example.addrpc", serializerEnableMaxDepthChecks=true, worker="posts") */ public function addAction(Post $post)
-
在类上使用
@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 客户端上使用。