WebsocketServer.Class.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <?php
  2. namespace Mall\Framework\Swoole;
  3. class WebsocketServer
  4. {
  5. private $moduleServer;
  6. private $moduleData;
  7. private $serviceModuleName;
  8. private $isSetConfig;
  9. function __construct($options = [])
  10. {
  11. class_exists('swoole_websocket_server') or die("swoole_websocket_server: check swoole extension");
  12. if($options['ssl'] == true){
  13. $this->moduleServer = new \swoole_websocket_server($options['host'], $options['port'], SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
  14. }else{
  15. $this->moduleServer = new \swoole_websocket_server($options['host'], $options['port']);
  16. }
  17. if (!isset($options['module']) && $options['module']) {
  18. throw new \Exception('Please define the module name first');
  19. }
  20. $this->serviceModuleName = ucfirst($options['module']);
  21. }
  22. public function setConfig($options = [])
  23. {
  24. $defaultOptions = [
  25. 'worker_num' => 8, // 建议开启核数的1-4倍
  26. 'daemonize' => true,
  27. ];
  28. $options = $options ?: $defaultOptions;
  29. $this->moduleServer->set($options);
  30. $this->isSetConfig = true;
  31. return $this;
  32. }
  33. public function begin()
  34. {
  35. if (!$this->isSetConfig) {
  36. throw new \Exception('Please set the configuration file first');
  37. }
  38. $this->registerEvent();
  39. $this->moduleServer->start();
  40. }
  41. private function registerEvent()
  42. {
  43. $this->moduleServer->on('Start', array($this, 'onStart'));
  44. $this->moduleServer->on('Connect', array($this, 'onConnect'));
  45. $this->moduleServer->on('open', array($this, 'onOpen'));
  46. $this->moduleServer->on('message', array($this, 'onMessage'));
  47. $this->moduleServer->on('Close', array($this, 'onClose'));
  48. //$this->moduleServer->on('ManagerStart', array($this, 'onManagerStart'));
  49. //$this->moduleServer->on('WorkerStart', array($this, 'onWorkerStart'));
  50. //$this->moduleServer->on('WorkerStop', array($this, 'onManagerStop'));
  51. }
  52. //启动server时候会触发。
  53. public function onStart($server)
  54. {
  55. echo "Start swoole_websocket_server \n";
  56. }
  57. //client连接成功后触发。
  58. public function onConnect($server, $fd, $from_id)
  59. {
  60. echo "Client id {$fd}:{$from_id} \n";
  61. //var_dump($this->moduleServer->connection_info($fd));
  62. }
  63. //client连接成功后触发。
  64. public function onOpen(\swoole_websocket_server $server, $request)
  65. {
  66. echo "server: handshake success with fd{$request->fd}\n";
  67. }
  68. //接收client发过来的请求
  69. public function onMessage( $server, $frame)
  70. {
  71. $moduleData = str_replace(PACKAGE_EOF, '', $frame->data);
  72. echo "Get Message From Client {$frame->fd}:{$moduleData}\n";
  73. if (!$moduleData = json_decode($moduleData, true)) {
  74. throw new \Exception('Please send data to JSON format');
  75. }
  76. $namespace = '\Service\\' . $this->serviceModuleName . '\\Controller\\' . $moduleData['controller'];
  77. $resource = new $namespace();
  78. if (isset($moduleData['params']) && $moduleData['params']) {
  79. $moduleData['params']['fromId'] = $frame->fd;
  80. $data = call_user_func([$resource, $moduleData['action']], $moduleData['params']);
  81. } else {
  82. $data = call_user_func([$resource, $moduleData['action']]);
  83. }
  84. try{
  85. if(!empty($data)){
  86. $result = true;
  87. foreach ($data['fromId'] as $key => $value){
  88. if($server->exist($value)){
  89. $result = $server->push($value, $data['sendData']);
  90. }else{
  91. echo "Client {$value} connect not exist\n";
  92. }
  93. }
  94. if(!in_array($frame->fd, $data['fromId'])){
  95. $result = $server->push($frame->fd, json_encode(['state'=>true,'data'=>'服务端脚本完毕']));
  96. }
  97. }else{
  98. $result = $server->push($frame->fd, json_encode(['state'=>false,'data'=>'服务端脚本处理异常']));
  99. }
  100. }catch (\Exception $e){
  101. echo $e->getMessage();
  102. }
  103. if(!$result){
  104. echo $this->moduleServer->getLastError();
  105. }
  106. }
  107. //客户端断开触发
  108. public function onClose($server, $fd)
  109. {
  110. echo "Client {$fd} close connection\n";
  111. $namespace = '\Service\BaseController';
  112. $resource = new $namespace();
  113. if(method_exists($resource, 'closeWebstock')){
  114. if( call_user_func([$resource, 'closeWebstock'], $fd) ){
  115. echo 'logout redis success';
  116. }
  117. }
  118. }
  119. public function onManagerStart(\swoole_server $server) {
  120. echo "On manager start.";
  121. }
  122. public function onManagerStop(\swoole_server $server) {
  123. echo "On manager start.";
  124. }
  125. public function onWorkerStart(\swoole_server $server, $workerId) {
  126. echo $workerId . '---';
  127. }
  128. public function getData()
  129. {
  130. return $this->moduleData;
  131. }
  132. }