首先,改造Router.php
在 SWOOLE 从入门到放弃之写个小框架(八) 中,已经写好了处理HTTP请求路由的方法,接下来就开始写处理WEBSOCKET请求路由的方法。
开始写WEBSOCKET请求路由前,我需要确定一个数据交互的数据格式,比如,客户端发起请求后,我们要根据请求的内容来路由到指定的module->controller->action上,并且在需要时还要带上相应的参数,首选就是JSON,原因就是JSON格式清晰简单,兼容性也比较好。我们先设定一个最基本的拉取用户信息的格式
{
"cmd":"user/info/get", //请求地址,对应module->controller->action
"uid": 1 // 参数
}
有了这个大前提,Router.php就很容易改造了。拿到websocket的数据帧后,直接把json格式解析成数组格式,然后还希望它能像http路由那样URL重写缩短URL地址。代码如下
/**
* WebSocket 路由解析
*/
public function websocket($data) {
$data = json_decode ($data , true );
if(empty($data)){
echo 'WEBSOCKET-json解包错误',PHP_EOL;
return ['m'=>NULL ,'c'=>NULL,'a'=>NULL ,'p' => NULL] ;
}
$path = empty($data['cmd']) ? '' : trim($data['cmd'], '/');
if(empty($path)){
echo '请求地址错误',PHP_EOL;
return ['m'=>NULL ,'c'=>NULL,'a'=>NULL ,'p' => NULL] ;
}
if (!empty(self::$config['rules']) && isset(self::$config['rules'][$path])) {
$path = self::$config['rules'][$path];
}
$param = explode( "/" , $path);
$module = array_shift ($param);
$controller = array_shift ($param);
$action = array_shift ($param);
unset($data['cmd']);
return ['m'=>$module ,'c'=>$controller,'a'=>$action ,'p' => $data] ;
}
Router.php改造完成,代码请移步 https://gitee.com/pizzzz/piz/blob/master/frame/Lib/Router.php
接下来改造App.php。
使用同样的方式,把http和websocket的处理方式分开,在App.php新增websocket方法。为了能让项目中的控制器可以直接向客户端推送内容,我们需要在它初始化时把server对象传递给控制器,同时还要把fd也传过去,代码如下
public function websocket($server,$frame)
{
$router = $router = Router::get_instance ()->websocket( $frame ->data );
$app_namespace = Config::get_instance ()->get('app.namespace');
$module = $router['m'] ;
$controller = $router['c'] ;
$action = $router['a'] ;
$param = $router['p'] ;
$classname = "\\{$app_namespace}\\modules\\{$module}\\{$controller}";
if ( ! isset( self ::$map[ $classname ] ) ) {
try{
$class = new $classname;
self ::$map[ $classname ] = $class;
}catch (\Exception $e){
echo $e->getMessage (),PHP_EOL;
return ;
}
}
try{
self::$map[$classname]->server = $server;
self::$map[$classname]->fd = $frame->fd;
self::$map[$classname]->param = $param;
self::$map[$classname]->$action();
}catch(\Exception $e){
echo $e->getMessage (),PHP_EOL;
return ;
}
}
创建控制器文件 app/modules/user/info.php,代码如下
<?php
namespace app\modules\user;
class info
{
public function get(){
$content = "Uid:{$this->param['uid']};Name:test;say:{$this->param['msg']}";
$this->server->push($this->fd,$content);
}
}
启动start.php,访问http://192.168.1.111:9501/ws.html
运行效果如下
代码已上传至码云 https://gitee.com/pizzzz/piz
下一篇 , 用TASK来实现WEBSOCKET的批量回复
共同学习,写下你的评论
评论加载中...
作者其他优质文章