业务背景
做的是一款游戏匹配的 App,PHP 使用 swoole 创建 websocket 提供游戏的匹配服务
匹配流程如下
- 对匹配者的鉴权 (握手事件处理)
- 匹配的业务逻辑 (比如男只能匹配到女,这块也是需要热更新,open 事件处理)
- 匹配成功返回数据,关闭连接
- 再往后就是 nodejs 去提供服务
想要达到的目的
关于热更新 swoole 官方文档
其实核心就是说你要热更新的代码必须在 onWorkerStart 事件中引入
安装 swoole 和 inotify
自己绘制的 "设计图"
如果你使用 artisan 启动 swoole 服务的话,可能会热更新失败,因为在 onWorkerStart,之前已经载入太多类
index
设置常量同时实例化 MatchServer 来启动服务
MatchServer
class MatchServer{ private $server; protected $application; function __construct () { // 创建swoole_table,用于进程间数据共享 $table = new swoole_table(1024); $table->column('fd',swoole_table::TYPE_INT); $table->column('uid',1)">$table->column('gameType',swoole_table::TYPE_STRING,256$table->column('data',1)">$table->create(); $this->server = new swoole_websocket_server("0.0.0.0",1)"> PORT); $this->server->table = $table; 注册回调事件 $this->server->on('handShake',1)">array($this,'onHandShake')); $this->server->on('workerStart','onWorkerStart'$this->server->on('open','onOpen'$this->server->on('message','onMessage'$this->server->on('close','onClose')); $this->server->start(); } /** * 处理握手 * * @param swoole_http_request $request * @param swoole_http_response $response * * @return bool */ public function onHandShake (\swoole_http_request $request,\swoole_http_response $response) { if(参数校验不通过) { $response->end(); return false; } swoole握手环节,因为我的匹配是在open事件处理,当自己处理握手之后,不会自动调用open事件,需自己调用 // 握手环节代码..太多..考虑到篇幅问题,不贴了..大家可以去swoole手册搜索 $this->onOpen($this->server,$request); true; } * * 载入框架入口文件,并设置inotify热更新目录 * * @param $server * @param $worker_id function onWorkerStart ($server,1)">$worker_id 载入框架入口文件 require ROOT_PATH.'public/index.PHP'; 实例化业务逻辑类 $this->application = new MatchApplication(); if ($worker_id == 0) { 设置热更新目录 $dir = app_path('Game/Match'); $list[] = $dir; foreach (array_diff(scandir($dir),1)">array('.','..')) as $item) { $dir.'/'.; } $notify = inotify_init(); foreach ($list ) { inotify_add_watch($notify,1)">$item,IN_CREATE | IN_DELETE | IN_MODIFY); } swoole_event_add(function () use ($events = inotify_read($notify); if (!empty($events)) { 执行swolle reload $server->reload(); } }); } } * * 处理匹配 * * @param $server * @param $request function onOpen ( 调用业务逻辑类的onOpen $this->application->onOpen(); } function onMessage ($frame){} * * 关闭连接同时删除swoole_table数据 * * @param $server * @param $fd function onClose ($fd 由于我进程间的数据共享用的swoole_table,所以连接关闭,需要删除数据 $server->table->exist()) { $server->table->del(); } } }
MatchApplication
* * 处理匹配业务逻辑 * * @param $server * @param $request */ ) { $fd = $request->fd; 处理业务逻辑...... $server->push($fd,1)">$data); $server->close(); }
启动服务
确认 onWorkerStart
之前没有载入你要热更新的代码
) { print_r(get_included_files()); return; }