• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 在 Laravel 中使用 GatewayWorker 进行 socket 长连接通讯

    初次接触GatewayWorker框架,先阅读示例:Linux系统快速开始(从一个精简的聊天demo开始)。查看文件目录结构:

    GatewayWorker
    ├── Applications     // 这里是所有开发者应用项目
    │   └── YourApp      // 其中一个项目目录,目录名可以自定义
    │       ├── Events.php        // 开发者只需要关注这个文件
    │       ├── start_gateway.php         // gateway进程启动脚本,包括端口号等设置
    │       ├── start_businessworker.php  // businessWorker进程启动脚本
    │       └── start_register.php        // 注册服务启动脚本
    │
    ├── start.php    // 全局启动脚本,此脚本会依次加载Applications/项目/start_*.php启动脚本
    │
    └── vendor       // GatewayWorker框架和Workerman框架源码目录,此目录开发者不用关心
    

    在 Laravel 框架中使用,有两种方式:

    • 方式一:根据示例,复制Applications目录下文件,到 Laravel 框架到app目录下,可以自定义新目录,并且修改start.php文件中的相应的加载位置。
    • 方式二:使用 Laravel 框架提供的php artisan命令工具来做启动。把start.phpstart_gateway.phpstart_register.phpstart_businessworker.php四个文件内容,合并在一起。


    1、安装 GatewayWorker

    composer require workerman/gateway-worker
    composer require workerman/gatewayclient
    

    2、创建 Workerman 启动文件

    创建一个 artisan 命令行工具来启动 Socket 服务端,在app/Console/Commands目录下建立命令行文件。

    php artisan make:command GatewayworkerCommand
    

    app/Console/Commands/GatewayworkerCommand 内容如下:

    <?php
    namespace App\Console\Commands;
    use Illuminate\Console\Command;
    use Workerman\Worker;
    use Workerman\WebServer;
    use Workerman\Autoloader;
    use GatewayWorker\Gateway;
    use GatewayWorker\Register;
    use GatewayWorker\BusinessWorker;
    use App\Gatewayworker\Events;
    
    class GatewayworkerCommand extends Command
    {
    
        protected $signature = 'Workerman {action} {--d}';
        protected $description = 'Start a Workerman server';
    
        public function __construct()
        {
            parent::__construct();
        }
    
    
        public function handle()
        {
            $this->startGateWay();
            $this->startBusinessWorker();
            $this->startRegister();
            Worker::runAll();
        }
    
        private function startBusinessWorker()
        {
            $worker                  = new BusinessWorker();
            $worker->name            = 'BusinessWorker';
            $worker->count           = 4;
            $worker->registerAddress = '127.0.0.1:1236';
            $worker->eventHandler    = \App\Gatewayworker\Events::class;
        }
     
        private function startGateWay()
        {
            $gateway = new Gateway("websocket://0.0.0.0:2346");
            $gateway->name                 = 'Gateway';
            $gateway->count                = 4;
            $gateway->lanIp                = '127.0.0.1';
            $gateway->registerAddress      = '127.0.0.1:1236';      
        }
     
        private function startRegister()
        {
            new Register('text://0.0.0.0:1236');
        }
    }
    


    3、创建事件监听文件

    创建一个app/Gatewayworker/Events.php文件来监听处理 workman 的各种事件。

    <?php
    namespace App\Gatewayworker; 
    use GatewayWorker\Lib\Gateway;
     
    class Events
    {
     
        public static function onWorkerStart($businessWorker)
        {
            echo "onWorkerStart\r\n";
        }
     
        public static function onConnect($client_id)
        {
            Gateway::sendToClient($client_id, json_encode(['type' => 'onConnect', 'client_id' => $client_id]));
            echo "onConnect\r\n";
        }
     
        public static function onWebSocketConnect($client_id, $data)
        {
            echo "onWebSocketConnect\r\n";
        }
     
        public static function onMessage($client_id, $message)
        {
            Gateway::sendToClient($client_id, json_encode(['type' => 'onMessage', 'client_id' => $client_id, 'name' => json_decode($message)->name]));
     
            echo "onMessage\r\n";
        }
     
        public static function onClose($client_id)
        {
            echo "onClose\r\n";
        }
     
    }
    


    4、开启服务

    在命令行里面执行,支持的命令有start|stop|restart,其中--d的意思是 daemon 模式,后台守护进程。

    php artisan workerman start
    

    显示如下:

    Workerman[artisan] start in DEBUG mode
    -------------------------------------------- WORKERMAN ---------------------------------------------
    Workerman version:4.0.20          PHP version:8.0.12
    --------------------------------------------- WORKERS ----------------------------------------------
    proto   user            worker            listen                      processes    status
    tcp     root            Gateway           websocket://0.0.0.0:2346    4             [OK]
    tcp     root            BusinessWorker    none                        4             [OK]
    tcp     root            Register          text://0.0.0.0:1236         1             [OK]
    ----------------------------------------------------------------------------------------------------
    Press Ctrl+C to stop. Start success.
    onWorkerStart
    onWorkerStart
    onWorkerStart
    onWorkerStart
    


    5、在浏览器中测试

    用 chrome 浏览器打开此 Laravel 框架建设的网站,打开控制台(快捷键按F12)。在Console里输入:

    var ws = new WebSocket("ws://127.0.0.1:2346");
    
    ws.onopen = function(e) {
    	ws.send('{"name":"one","user_id":"111"}');
            ws.send('{"name":"two","user_id":"222"}');
    };
    
    ws.onmessage = function(e) {
            console.log("收到服务端的消息:" + e.data);
    };
    
    ws.onclose = function(e) {
            console.log("服务已断开" );
    }
    

    成功!