TCP 控制器

定义

  1. <?php
  2. namespace ImiDemo\TcpDemo\MainServer\Controller;
  3. use Imi\ConnectContext;
  4. use Imi\Server\Route\Annotation\Tcp\TcpRoute;
  5. use Imi\Server\Route\Annotation\Tcp\TcpAction;
  6. use Imi\Server\Route\Annotation\Tcp\TcpController;
  7. /**
  8. * 数据收发测试
  9. * @TcpController
  10. */
  11. class Test extends \Imi\Controller\TcpController
  12. {
  13. /**
  14. * 登录
  15. *
  16. * @TcpAction
  17. * @TcpRoute({"action"="login"})
  18. * @return void
  19. */
  20. public function login($data)
  21. {
  22. ConnectContext::set('username', $data->username);
  23. $this->server->joinGroup('g1', $this->data->getFd());
  24. return ['action'=>'login', 'success'=>true];
  25. }
  26. }

首先控制器类必须有@TcpController注解,对应动作必须有@TcpAction@TcpRoute注解。

注解

@TcpRoute

指定 Tcp 路由解析规则。

  1. // 解析 $data['action'] === 'login'
  2. @WSRoute({"action"="login"})
  3. // 解析 $data['a']['b']['c'] === 'login'
  4. @WSRoute({"a.b.c"="login"})
  5. // 解析 $data['a'] == '1' && $data['b'] == '2'
  6. @WSRoute({"a"="1", "b"="2"})

当然对象也是支持的:

  1. // 解析 $data->a->b->c === 'login'
  2. @WSRoute({"a.b.c"="login"})

路由匹配成功,就会执行这个动作。

动作响应数据

响应当前这个请求

直接在方法中返回一个数组或对象,在服务器配置设定的处理器,就会把这个转为对应数据响应给客户端。

配置文件

  1. return [
  2. // 主服务器配置,提供websocket服务
  3. 'mainServer' => [
  4. 'namespace' => 'ImiDemo\TcpDemo\MainServer',
  5. 'type' => Type::TCP_SERVER,
  6. // 'host' => '0.0.0.0',
  7. 'port' => 8085,
  8. // 'mode' => SWOOLE_BASE,
  9. // 'sockType' => SWOOLE_SOCK_TCP,
  10. 'configs' => [
  11. 'reactor_num' => 2,
  12. 'worker_num' => 2,
  13. 'task_worker_num' => 8,
  14. // EOF自动分包
  15. 'open_eof_split' => true, //打开EOF_SPLIT检测
  16. 'package_eof' => "\r\n", //设置EOF
  17. ],
  18. // 数据处理器
  19. 'dataParser' => \ImiDemo\TcpDemo\MainServer\Parser\JsonObjectParser::class,
  20. ],
  21. }

响应数据

  1. return ['success'=>true];

分组发送

  1. $this->server->groupCall('组名', 'push', ['success'=>true]);

当然,并不是每个请求都需要有响应数据,什么都不return或者return null就是不响应数据。

类属性

$server

方法

getSwooleServer

获取Swoole的Server对象

  1. /**
  2. * 组是否存在
  3. *
  4. * @param string $groupName
  5. * @return boolean
  6. */
  7. public function hasGroup(string $groupName);
  1. /**
  2. * 创建组,返回组对象
  3. *
  4. * @param string $groupName
  5. * @param integer $maxClients
  6. * @return \Imi\Server\Group\Group
  7. */
  8. public function createGroup(string $groupName, int $maxClients = -1);
  1. /**
  2. * 获取组对象,不存在返回null
  3. *
  4. * @param string $groupName
  5. * @return \Imi\Server\Group\Group|null
  6. */
  7. public function getGroup(string $groupName);
  1. /**
  2. * 加入组,组不存在则自动创建
  3. *
  4. * @param string $groupName
  5. * @param integer $fd
  6. * @return void
  7. */
  8. public function joinGroup(string $groupName, int $fd);
  1. /**
  2. * 离开组,组不存在则自动创建
  3. *
  4. * @param string $groupName
  5. * @param integer $fd
  6. * @return void
  7. */
  8. public function leaveGroup(string $groupName, int $fd);
  1. /**
  2. * 调用组方法
  3. *
  4. * @param string $groupName
  5. * @param string $methodName
  6. * @param mixed ...$args
  7. * @return array
  8. */
  9. public function groupCall(string $groupName, string $methodName, ...$args);
  1. /**
  2. * 获取所有组列表
  3. *
  4. * @return \Imi\Server\Group\Group[]
  5. */
  6. public function getGroups(): array;

$frame

方法

  1. /**
  2. * 获取客户端的socket id
  3. * @return int
  4. */
  5. public function getFd(): int;
  1. /**
  2. * 数据内容,可以是文本内容也可以是二进制数据,可以通过opcode的值来判断
  3. * @return string
  4. */
  5. public function getData();
  1. /**
  2. * 获取格式化后的数据,一般是数组或对象
  3. * @return mixed
  4. */
  5. public function getFormatData();
  1. /**
  2. * 获取Reactor线程ID
  3. *
  4. * @return int
  5. */
  6. public function getReactorID(): int;

控制器类方法

encodeMessage

  1. /**
  2. * 编码消息,把数据编码为发送给客户端的格式
  3. *
  4. * @param mixed $data
  5. * @return mixed
  6. */
  7. protected function encodeMessage($data)