TCP 控制器
优质
小牛编辑
130浏览
2023-12-01
定义
<?php
namespace ImiDemo\TcpDemo\MainServer\Controller;
use Imi\ConnectContext;
use Imi\Server\Route\Annotation\Tcp\TcpRoute;
use Imi\Server\Route\Annotation\Tcp\TcpAction;
use Imi\Server\Route\Annotation\Tcp\TcpController;
/**
* 数据收发测试
* @TcpController
*/
class Test extends \Imi\Controller\TcpController
{
/**
* 登录
*
* @TcpAction
* @TcpRoute({"action"="login"})
* @return void
*/
public function login($data)
{
ConnectContext::set('username', $data->username);
$this->server->joinGroup('g1', $this->data->getFd());
return ['action'=>'login', 'success'=>true];
}
}
首先控制器类必须有@TcpController
注解,对应动作必须有@TcpAction
和@TcpRoute
注解。
注解
@TcpRoute
指定 Tcp 路由解析规则。
// 解析 $data['action'] === 'login'
@TcpRoute({"action"="login"})
// 解析 $data['a']['b']['c'] === 'login'
@TcpRoute({"a.b.c"="login"})
// 解析 $data['a'] == '1' && $data['b'] == '2'
@TcpRoute({"a"="1", "b"="2"})
当然对象也是支持的:
// 解析 $data->a->b->c === 'login'
@TcpRoute({"a.b.c"="login"})
路由匹配成功,就会执行这个动作。
动作响应数据
响应当前这个请求
直接在方法中返回一个数组或对象,在服务器配置设定的处理器,就会把这个转为对应数据响应给客户端。
配置文件
return [
// 主服务器配置,提供websocket服务
'mainServer' => [
'namespace' => 'ImiDemo\TcpDemo\MainServer',
'type' => Type::TCP_SERVER,
// 'host' => '0.0.0.0',
'port' => 8085,
// 'mode' => SWOOLE_BASE,
// 'sockType' => SWOOLE_SOCK_TCP,
'configs' => [
'reactor_num' => 2,
'worker_num' => 2,
'task_worker_num' => 8,
// EOF自动分包
'open_eof_split' => true, //打开EOF_SPLIT检测
'package_eof' => "\r\n", //设置EOF
],
// 数据处理器
'dataParser' => \ImiDemo\TcpDemo\MainServer\Parser\JsonObjectParser::class,
],
}
响应数据
return ['success'=>true];
分组发送
$this->server->groupCall('组名', 'push', ['success'=>true]);
当然,并不是每个请求都需要有响应数据,什么都不return
或者return null
就是不响应数据。
指定连接发送数据
以下代码写在控制器的代码中,总而言之,如果你要推送消息,你得拿到SwooleServer
对象。
// $server 对象是 \Swoole\Server类型
$server = $this->server->getSwooleServer();
// 指定连接
$fd = 19260817;
$data = 'hello imi';
// 原样发送数据
$server->send($fd, $data);
// 使用预定义的编码器,编码后发送数据
$server->send($fd, $this->encodeMessage($data));
类属性
$server
方法
getSwooleServer
获取Swoole的Server对象
/**
* 组是否存在
*
* @param string $groupName
* @return boolean
*/
public function hasGroup(string $groupName);
/**
* 创建组,返回组对象
*
* @param string $groupName
* @param integer $maxClients
* @return \Imi\Server\Group\Group
*/
public function createGroup(string $groupName, int $maxClients = -1);
/**
* 获取组对象,不存在返回null
*
* @param string $groupName
* @return \Imi\Server\Group\Group|null
*/
public function getGroup(string $groupName);
/**
* 加入组,组不存在则自动创建
*
* @param string $groupName
* @param integer $fd
* @return void
*/
public function joinGroup(string $groupName, int $fd);
/**
* 离开组,组不存在则自动创建
*
* @param string $groupName
* @param integer $fd
* @return void
*/
public function leaveGroup(string $groupName, int $fd);
/**
* 调用组方法
*
* @param string $groupName
* @param string $methodName
* @param mixed ...$args
* @return array
*/
public function groupCall(string $groupName, string $methodName, ...$args);
/**
* 获取所有组列表
*
* @return \Imi\Server\Group\Group[]
*/
public function getGroups(): array;
$data
方法
/**
* 获取客户端的socket id
* @return int
*/
public function getFd(): int;
/**
* 数据内容,可以是文本内容也可以是二进制数据,可以通过opcode的值来判断
* @return string
*/
public function getData();
/**
* 获取格式化后的数据,一般是数组或对象
* @return mixed
*/
public function getFormatData();
/**
* 获取Reactor线程ID
*
* @return int
*/
public function getReactorID(): int;
控制器类方法
encodeMessage
/**
* 编码消息,把数据编码为发送给客户端的格式
*
* @param mixed $data
* @return mixed
*/
protected function encodeMessage($data)