yii2-swoole-websocket,支持 JSONRPC,基于 method 参数路由 [ 2.0 版本 ]
https://github.com/immusen/yii2-swoole-websocket
支持通过websocket、http、redis publish发送JSONRPC触发swoole worker执行异步任务和即时通信
示例:
聊天室案例, 示例代码: /websocket/controllers/RoomController.php
发送消息:
{
"jsonrpc":"2.0",
"id":1,
"method":"room/msg",
"params":{
"id":"100111",
"content":{
"text":"Hello world!"
}
}
}
聊天室成员接收消息:
{
"jsonrpc":"2.0",
"id":1,
"result":{
"text":"Hello world!"
}
}
开发:
1, 在websocket/controllers目录下创建Controller, (也可以是其它路径, 只需修改config/main.php中controllerNamespace配置)
<?php
namespace websocket\controllers;
use immusen\websocket\src\Controller;
class FooController extends Controller
{
public function actionBar($param_1, $param_2 = 0, $param_n = null)
{
# addFds把当前客户端fd存储到一个集合, $param_1作为Key(其它字符串亦可)
$this->joinGroup($this->fd, $param_1);
# 向当前websocket客户端发送信息
$this->publish($this->fd, ['p1' => $param_1, 'p2' => $param_2]);
# 从集合中取出所有客户度fd
$fds_array = $this->getFds($param_1);
# 群发消息给集合中的客户端
$this->publish($fds_array, ['p1' => $param_1, 'p2' => $param_2]);
#或
$this->sendToGroup(['p1' => $param_1, 'p2' => $param_2], $param_1);
# 通过redis连接池操作redis
$this->redis->set($param_1, 0)
}
}
2, 发送JSONRPC, 并指定method为"foo/bar"即可调用上述action
{
"jsonrpc":"2.0",
"id":1,
"method":"foo/bar",
"params":{
"param_1":"client_01",
"param_2":100,
"param_n":{
"time":1551408888,
"type":"report"
}
}
}
所有的客户端到服务器的RPC调用, 除用websocket客户端之外, 也可以使用HTTP或Redis Publish来投递, 该特性可以用于Yii Web应用向Swoole worker投递异步任务(例如发短信..), 在聊天室例子中, 可以这样操作:
HTTP 请求:
http://127.0.0.1:8721/rpc?p={"jsonrpc":"2.0","id":1,"method":"room/msg","params":{"id":"100111","content":{"text":"System warning!"}}}
或 redis-cli:
127.0.0.1:6379> publish rpc '{"jsonrpc":"2.0","id":1,"method":"room/msg","params":{"id":"100111","content":{"text":"System warning!"}}}'
或 在Yii web 应用中
Yii:$app->redis->publish('rpc', '{"jsonrpc":"2.0","id":1,"method":"room/msg","params":{"id":"100111","content":{"text":"System warning!"}}}')
或通过Hook(推荐方式), 支持runOnce, 确保任务即使在多Swoole实例/分布式的情况下只执行一次, 详见immusen/yii2-swoole-websocket/Hook.php
Yii::$app->hook->run('room/msg', ['id' => 100111, 'content' => ['text' => 'System warning!']]);
升级中, 可能继续新增http session, auth, 丰富配置, 以及简化web app向swoole worker投递异步任务机制...
immusen 北京
注册时间:2015-09-24
最后登录:2024-04-17
在线时长:16小时32分
最后登录:2024-04-17
在线时长:16小时32分
- 粉丝6
- 金钱520
- 威望40
- 积分1080
共 8 条评论
大佬今天我用了下,貌似这个是高级版的,没有基础版的吗。。
启动服务就报错了
想着注释掉,但是引用的太多了,都不知道路径,麻烦大佬出个基础版的吧,
没用基础版版测试,但简单来说,你可以这么干,把配置文件都挪出来放到启动脚本websocket-server里:
#!/usr/bin/env php <?php defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'dev'); defined('STDIN') or define('STDIN', fopen('php://stdin', 'r')); defined('STDOUT') or define('STDOUT', fopen('php://stdout', 'w')); defined('STDERR') or define('STDERR', fopen('php://stderr', 'w')); require __DIR__ . '/vendor/autoload.php'; require __DIR__ . '/vendor/yiisoft/yii2/Yii.php'; //require __DIR__ . '/common/config/bootstrap.php'; //require __DIR__ . '/websocket/config/bootstrap.php'; //$config = yii\helpers\ArrayHelper::merge( // require __DIR__ . '/common/config/main.php', // require __DIR__ . '/common/config/main-local.php', // require __DIR__ . '/websocket/config/main.php', // require __DIR__ . '/websocket/config/main-local.php' //); Yii::setAlias('@immusen/websocket', __DIR__ . '/vendor/immusen/yii2-swoole-websocket'); Yii::setAlias('@websocket', __DIR__ . '/websocket'); $config = [ 'id' => 'websocket', 'basePath' => __DIR__ . '/websocket', 'bootstrap' => ['log'], 'controllerNamespace' => 'websocket\controllers', 'components' => [ 'errorHandler' => ['class' => 'yii\console\ErrorHandler'], 'log' => [ 'targets' => [ [ 'class' => 'yii\log\FileTarget', 'levels' => ['error', 'warning'], ], ], ], ], 'params' => [ 'listen' => 8721, 'daemonize' => 0, 'redis' => [ 'host' => '127.0.0.1', 'port' => '6379', // 'auth' => 'passwd', 'pool_size' => 10, ], ], ]; $application = new immusen\websocket\Application($config); $exitCode = $application->run(); exit($exitCode);
谢谢回复。
新升级:启动脚本支持更多操作
@immusen 感谢大神的解答,已经用此功能完成了一个小任务了,成就感满满,特此感谢!
你就是最近经常邮件提问那位吧?任务成功了、技能提升了,很好!我也分享到了你的成就感...
是的,是我,是我~
期待有机会继续跟您讨论技术问题,开心!~
Ok,没问题..
请问这个的应用场景是什么,是内部服务调用吗 比如分布式系统下的服务互相调用
主要就是websocket服务端,其次是可以执行一些异步任务比如发短信, jsonrpc只是一个通用的约定,让其它应用可以轻易向这个应用发指令,然后通过将指令和参数反射到controller/action,简化业务开发。基本上GatewayWorker能干的事情,这个扩展也能干...
请问为什么找不到 use Swoole\Websocket\Server 这个类呢?Swoole 也安装了啊,谢谢
运行php --ri swoole 看下输出,确定swoole是否安装好,版本号是否4+, swoole.use_namespace => On是否开启了使用命名空间。
您好,请问一下,我在 Yii2 下使用,但是会导致服务器 CPU 爆表然后死机,请问是哪里需要特别设置吗?服务器 4核CPU 16GB 内存,谢谢
服务器内使用 docker, nginx-yii2 框架。
请问这个 docker 的 web root 可以设置在 websocket 这个目录吗?
开始服务器后,内存会一直增加,然后服务器就挂了?
短短显示出 #client closed 高达 100多亿,然后服务器就挂了...
在什么环境下测试的呢? 确有那么多client连接嘛?