关于laravel artisan命令启动swoole服务,swoole热更新问题

业务需求

做一个游戏匹配的app php这边用了swoole来创建websocket服务来完成匹配环节

具体步骤

  • 携带参数连接websocket匹配
  • 握手环节校验参数,参数校验不过,握手失败
  • 进入websocket onOpen回调函数,处理匹配流程
  • 匹配成功,给双方下发连接游戏服务的参数,客户端根据参数,连接游戏服务

热更新需求

因为,匹配逻辑可能变动(比如男生只能匹配到女生....),所以具体执行匹配的业务逻辑代码是需要热更新的.

创建websocket的代码

我这里用了laravel的artisan命令来启动swoole服务,点这里

use swoole_table;
use App\Models\User;
use App\Models\Game;
use swoole_http_request;
use swoole_http_response;
use swoole_websocket_server;
use Illuminate\Console\Command;
use App\Game\GameMatch as GameMatchController;

class GameMatch extends Command
{
    protected $signature = 'game:match {action} {--daemonize}';

    protected $description = 'swoole启动匹配服务器';

    public function __construct ()
    {
        parent::__construct();
    }

    public function handle ()
    {
        var_dump(get_included_files());die;
        $action = $this->argument('action');
        if (!in_array($action, ['start', 'stop', 'restart', 'reload', 'status', 'connections'])) {
            $this->error('参数错误!!!');
            exit;
        }
        switch ($action) {
            case 'start':
                $this->info('started');
                $this->start();
                break;
        }
    }

    public function start ()
    {
        /** 建立table */
        $table = new swoole_table(200000);
        $table->column('fd', swoole_table::TYPE_INT);
        $table->column('uid', swoole_table::TYPE_INT);
        $table->column('gameType', swoole_table::TYPE_STRING, 256);
        $table->column('data', swoole_table::TYPE_STRING, 256);
        $table->create();

        $this->server = new swoole_websocket_server("0.0.0.0", 20005);
        $this->server->table = $table;

        $this->server->on('WorkerStart',function($serv, $worker_id){
            // 此处我用了 inotify 去监听app目录下的问题,如果有更改就$serv->reload(),篇幅太长.不贴出
        });

        $handle = app()->make(GameMatchController::class);

        //事件绑定到GameMatch类上
        $this->server->on('open', array($handle, 'onOpen'));
        $this->server->on('message', array($handle, 'onMessage'));
        $this->server->on('close', array($handle, 'onClose'));

        $this->server->on('handshake', function (\swoole_http_request $request, \swoole_http_response $response) use($handle) {
            // 此处是握手代码...由于篇幅问题,就不贴出
        });

        $this->server->start();
    }

个人理解(我也不知道对不对)

我个人的理解是由于artisan命令在启动的时候就已经载入了vendor/autoload.php 以及框架的一些东西,所以在swoole start之前这些东西就已经载入了..自然后面 inotify 检测到文件变化..也执行了swoole 的reload,但是这些文件都已经在启动前就载入了,自然也不会更新

但是我用artisan命令启动好处很多..这样我就可以用laravel提供的很多便捷的操作..查询数据库非常方便

file

inotify 也检测到了代码变化..同时也自动reload了..但是没有热更新成功

file

疑问,我如何在使用artisan命令启动服务的情况下,热更代码呢?