larkit/yii2-swoole-websocket

基于swoole 4的Yii2 WebSocket服务器,支持JSONRPC,将'method'解析为路由映射到控制器/操作,并支持通过http或redis pub/sub从您的Web应用程序触发异步任务。

安装: 55

依赖项: 0

建议者: 0

安全性: 0

星标: 0

关注者: 1

分支: 12

类型:yii2-extension

v2.0 2022-01-19 14:12 UTC

This package is auto-updated.

Last update: 2024-09-19 20:08:25 UTC


README

基于swoole 4的Yii2 WebSocket服务器,支持JSON-RPC,将'method'解析为路由映射到控制器/操作,并支持通过http或redis pub/sub从您的Web应用程序触发异步任务。

安装

安装Yii2: Yii2.

安装swoole: swoole,建议版本4+。

其他依赖:php-redis 扩展。

建议通过composer安装此扩展。

运行以下命令之一:

php composer.phar require --prefer-dist immusen/yii2-swoole-websocket "~1.0"

"immusen/yii2-swoole-websocket": "~1.0"

将以下内容添加到您的composer.json文件的require部分。

测试或使用

安装后,切换到项目根目录,例如:cd yii2-advanced-project/

mv vendor/immusen/yii2-swoole-websocket/example/websocket ./
mv vendor/immusen/yii2-swoole-websocket/example/websocket-server ./
chmod a+x ./websocket-server

运行

./websocket-server start    //start server
./websocket-server restart  //restart server
./websocket-server reload  //reload task worker
./websocket-server status  //server status

config

vim ./websocket/config/params.php

或在./websocket/controllers/中进行编码

示例

聊天室演示,代码:./example/websocket/controllers/RoomController.php

客户端加入房间:websocket客户端发送

  {
      "jsonrpc":"2.0",
      "id":1,
      "method":"room/join",
      "params":{
          "id":"100111",
          "info":{
              "age":"19",
              "gender":"f"
          }
      }
  }

已加入相同房间(id:100111)的websocket客户端将收到如下消息

  {
      "jsonrpc":"2.0",
      "id":1,
      "result":{
          "type":"join",
          "count":85,
          "info":{
              "age":"19",
              "gender":"f"
          }
      }
  }

聊天消息websocket客户端发送

    {
        "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下创建控制器,或在websocket/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)
     {
          # add current fd into a group/set, make $param_1 or anyother string as the group/set key
          $this->joinGroup($this->fd, $param_1);
          
          # reply message to current client by websocket
          $this->publish($this->fd, ['p1' => $param_1, 'p2' => $param_2]);
          
          # get all fds stored in the group/set
          $fds_array = $this->groupMembers($param_1);
          
          # reply message to a group
          $this->publish($fds_array, ['p1' => $param_1, 'p2' => $param_2]);
          #or
          $this->sendToGroup(['p1' => $param_1, 'p2' => $param_2], $param_1);
          
          # operate redis via redis pool
          $this->redis->set($param_1, 0)
     }
    
     //...
}

2、发送JSON-RPC以触发该操作

    {
        "jsonrpc":"2.0",
        "id":1,
        "method":"foo/bar",
        "params":{
            "param_1":"client_01",
            "param_2":100,
            "param_n":{
                "time":1551408888,
                "type":"report"
            }
        }
    }

所有客户端到服务器的rpc命令也可以通过HTTP或Redis发布发送,这个特性可以帮助从Web应用程序触发的一些异步任务。例如在聊天室案例中

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!"}}}')

或使用钩子(推荐),支持'runOnce',即使有多个swoole实例在线,方法也只运行一次,@see immusen/yii2-swoole-websocket/Hook.php

Yii::$app->hook->run('room/msg', ['id' => 100111, 'content' => ['text' => 'System warning!']]);
Yii::$app->hook->runOnce('sms/send', ['mobile' => 15600008721, 'code' => '8721']);