服务定义

每一个Rpc服务都应继承自 EasySwoole\Rpc\AbstractService 类。该类的具体代码如下:

  1. namespace EasySwoole\Rpc;
  2. use EasySwoole\Component\TableManager;
  3. use Swoole\Coroutine;
  4. abstract class AbstractService
  5. {
  6. private $allowMethods = [];
  7. private $requests = [];
  8. private $responses = [];
  9. private $sockets = [];
  10. private $actions = [];
  11. /*
  12. * 禁止重写该方法,防止在构造函数中抛出异常
  13. */
  14. final public function __construct()
  15. {
  16. //支持在子类控制器中以private,protected来修饰某个方法不可见
  17. $list = [];
  18. $ref = new \ReflectionClass(static::class);
  19. $public = $ref->getMethods(\ReflectionMethod::IS_PUBLIC);
  20. foreach ($public as $item) {
  21. array_push($list, $item->getName());
  22. }
  23. $this->allowMethods = array_diff($list,
  24. [
  25. '__hook', '__destruct',
  26. '__clone', '__construct', '__call',
  27. '__callStatic', '__get', '__set',
  28. '__isset', '__unset', '__sleep',
  29. '__wakeup', '__toString', '__invoke',
  30. '__set_state', '__clone', '__debugInfo',
  31. 'serviceName','version','onTick','actionList'
  32. ]
  33. );
  34. }
  35. protected function onRequest(?string $action):?bool
  36. {
  37. return true;
  38. }
  39. protected function afterAction(?string $action)
  40. {
  41. }
  42. abstract public function serviceName():string ;
  43. /*
  44. * 每秒会执行一次,请自己实现间隔需求
  45. */
  46. public function onTick(Config $config)
  47. {
  48. }
  49. protected function onException(\Throwable $throwable)
  50. {
  51. throw $throwable;
  52. }
  53. protected function request():Request
  54. {
  55. return $this->requests[Coroutine::getCid()];
  56. }
  57. protected function response():Response
  58. {
  59. return $this->responses[Coroutine::getCid()];
  60. }
  61. protected function socket():Coroutine\Socket
  62. {
  63. return $this->sockets[Coroutine::getCid()];
  64. }
  65. protected function action(): ?string
  66. {
  67. return $this->actions[Coroutine::getCid()];
  68. }
  69. protected function actionNotFound(?string $action)
  70. {
  71. $this->response()->setStatus(Response::STATUS_SERVICE_ACTION_NOT_FOUND);
  72. }
  73. public function version():string
  74. {
  75. return '1.0';
  76. }
  77. public function actionList():array
  78. {
  79. return $this->allowMethods;
  80. }
  81. public function __hook(Request $request, Response $response, Coroutine\Socket $client)
  82. {
  83. $this->requests[Coroutine::getCid()] = $request;
  84. $this->responses[Coroutine::getCid()] = $response;
  85. $this->sockets[Coroutine::getCid()] = $client;
  86. $this->actions[Coroutine::getCid()] = $request->getAction();
  87. $actionName = $this->action();
  88. try {
  89. if ($this->onRequest($this->action()) !== false) {
  90. if (in_array($actionName, $this->allowMethods)) {
  91. $actionName = $this->action();
  92. $this->$actionName();
  93. } else {
  94. $this->actionNotFound($this->action());
  95. }
  96. }
  97. } catch (\Throwable $throwable) {
  98. //若没有重构onException,直接抛出给上层
  99. $this->onException($throwable);
  100. } finally {
  101. try {
  102. $this->afterAction($this->action());
  103. } catch (\Throwable $throwable) {
  104. $this->onException($throwable);
  105. }
  106. unset( $this->requests[Coroutine::getCid()]);
  107. unset( $this->responses[Coroutine::getCid()]);
  108. unset( $this->actions[Coroutine::getCid()]);
  109. unset( $this->sockets[Coroutine::getCid()]);
  110. }
  111. if($response->getStatus() === Response::STATUS_OK){
  112. TableManager::getInstance()->get($this->serviceName())->incr($actionName,'success');
  113. }else{
  114. TableManager::getInstance()->get($this->serviceName())->incr($actionName,'fail');
  115. }
  116. }
  117. }

注意,全部请求都会复用该实例。因此成员属性的修改访问是不安全的。请用上下文管理器实现变量存储。