Inheritance: extends MyQEE\Server\WorkerTCP
Beispiel #1
0
 public function onStart()
 {
     parent::onStart();
     if ($this->server->worker_id === 0 && in_array($this->server->setting['dispatch_mode'], [1, 3])) {
         # 如果 dispatch_mode 是 1, 3 模式, 开启定期清理数据
         swoole_timer_tick(1000 * 60, function () {
             foreach (Host::$table as $key => $item) {
                 $info = $this->server->connection_info($item['fd'], $item['from_id']);
                 if ($item['removed']) {
                     if ($info) {
                         $this->server->close($item['fd'], $item['from_id']);
                     }
                     # 移除内存数据
                     Host::$table->del($key);
                 } elseif (false === $info) {
                     # 连接已经关闭
                     Host::$table->del($key);
                     # 推送服务器
                     RPC::factory($item['fd'], $item['from_id'])->trigger('server.remove', $item->group, $item->id);
                     Server::$instance->debug("remove closed client#{$item['group']}.{$item['id']}: {$item['ip']}:{$item['port']}");
                 }
             }
         });
     } else {
         swoole_timer_tick(1000 * 60, function () {
             # 清理移除掉的 server
             $time = time();
             foreach (Host::$table as $key => $item) {
                 if ($item['removed'] && $item['removed'] - $time > 10) {
                     # 清理数据
                     Host::$table->del($key);
                 }
             }
         });
     }
 }
Beispiel #2
0
 /**
  * 连接一个RPC服务器
  *
  * @param $ip
  * @param $port
  * @return bool
  */
 public function connect($ip, $port)
 {
     if ($this->__client) {
         @$this->__client->close();
         $this->__client = null;
     }
     /**
      * @var RPC $rpc
      */
     $this->__ip = $ip;
     $this->__port = $port;
     $this->__closeByServer = false;
     $rpc = $this->__rpc;
     $key = $rpc::_getRpcKey();
     $client = new \Swoole\Client(SWOOLE_TCP, SWOOLE_SOCK_ASYNC);
     $client->on('receive', function ($client, $data) use($key) {
         $arr = explode(Server::$EOF, $data);
         foreach ($arr as $item) {
             if ($item === '') {
                 continue;
             }
             $tmp = @msgpack_unpack($item);
             if ($key) {
                 $tmp = Server::decryption($tmp, $key);
                 if (!$tmp) {
                     \MyQEE\Server\Server::$instance->warn('rpc decryption data fail. data: ' . $item);
                     continue;
                 }
             }
             switch ($tmp->type) {
                 case 'on':
                     $event = $tmp->event;
                     if (isset($this->__events[$event])) {
                         # 回调执行
                         call_user_func_array($this->__events[$event], $tmp->args);
                     } else {
                         \MyQEE\Server\Server::$instance->warn("unknown rpc {$this->__rpc} event: {$event}");
                     }
                     break;
                 case 'close':
                     $this->__closeByServer = true;
                     $this->__client = null;
                     break;
                 default:
                     \MyQEE\Server\Server::$instance->warn("unknown rpc type {$tmp->type}");
                     break;
             }
         }
     });
     $client->on('connect', function ($client) {
         if (isset($this->__events['connect'])) {
             # 回调自定义的事件
             call_user_func($this->__events['connect'], $client);
         }
     });
     $client->on('close', function ($client) {
         $this->__client = null;
         \MyQEE\Server\Server::$instance->warn("rpc connection closed, {$this->__ip}:{$this->__port}.");
         if (!$this->isClosedByServer()) {
             # 不是被服务器强制关闭的则自动重新连接
             $this->reconnect();
         }
         if (isset($this->__events['close'])) {
             # 回调自定义的事件
             call_user_func($this->__events['close'], $client);
         }
     });
     $client->on('error', function ($client) {
         $this->__client = null;
         \MyQEE\Server\Server::$instance->warn("rpc connection({$this->__ip}:{$this->__port}) error: " . socket_strerror($client->errCode));
         # 遇到错误则自动重连
         swoole_timer_after(3000, function () {
             $this->reconnect();
         });
         if (isset($this->__events['error'])) {
             # 回调自定义的事件
             call_user_func($this->__events['error'], $client);
         }
     });
     $this->__client = $client;
     # 发心跳包
     swoole_timer_tick(1000 * 60 * 5, function () {
         if ($this->__client && $this->__client->isConnected()) {
             $this->__client->send("" . Server::$EOF);
         }
     });
     $this->__client->connect($ip, $port);
     return true;
 }
Beispiel #3
0
 protected function callbackByString($str, $rs = false)
 {
     if ($obj = @msgpack_unpack($str)) {
         unset($str);
         if ($this->key) {
             $obj = \MyQEE\Server\RPC\Server::decryption($obj, $this->key);
         }
         if (!$obj) {
             Server::$instance->warn('decryption task result data error');
         }
         if ($rs) {
             return $obj;
         } else {
             $this->callbackFinish($obj->id, $obj->data, $obj->wname);
         }
     }
     return null;
 }
Beispiel #4
0
 public function onReceive($server, $fd, $fromId, $data)
 {
     /**
      * @var \Swoole\Server $server
      */
     $tmp = @msgpack_unpack($data);
     if ($tmp && is_object($tmp)) {
         $data = $tmp;
         unset($tmp);
         if ($data instanceof \stdClass) {
             if ($data->bind) {
                 # 绑定进程ID
                 $server->bind($fd, $data->id);
                 return;
             }
             if ($key = \MyQEE\Server\Register\Client::$host->key) {
                 # 需要解密
                 $data = \MyQEE\Server\RPC\Server::decryption($data, $key);
                 # 解密失败
                 if (!$data) {
                     return;
                 }
             }
             $eof = \MyQEE\Server\RPC\Server::$EOF;
             switch ($data->type) {
                 case 'task':
                 case 'taskWait':
                     $rs = Server::$workerTask->onTask($server, $data->id, $data->wid, $data->data, $data->sid);
                     if ($rs !== null || $data->type === 'taskWait') {
                         # 执行 Finish
                         $rsData = new \stdClass();
                         $rsData->id = $data->id;
                         $rsData->data = $rs;
                         $rsData->wname = $data->wname;
                         if ($key) {
                             # 加密数据
                             $rsData = \MyQEE\Server\RPC\Server::encrypt($rsData, $key) . $eof;
                         } else {
                             # 格式化数据
                             $rsData = msgpack_pack($rsData) . $eof;
                         }
                         $server->send($fd, $rsData, $fromId);
                     }
                     break;
             }
         }
     } else {
         Server::$instance->warn("task server get error msgpack data length: " . strlen($data));
         Server::$instance->debug($data);
         $this->server->close($fd);
     }
 }