Esempio n. 1
0
 protected function request($request)
 {
     $runDir = $this->service->getRunDir();
     $port = (include $runDir . 'service-port.php');
     $sockFile = $runDir . 'service-' . $port . '.sock';
     $client = new Client(SWOOLE_UNIX_STREAM);
     $client->set(['open_length_check' => true, 'package_length_type' => 'N', 'package_length_offset' => 0, 'package_body_offset' => 4]);
     if (!@$client->connect($sockFile, 0, 20)) {
         return false;
     }
     $request = serialize($request);
     $client->send(pack('N', $length = strlen($request)));
     if ($length > 2097152) {
         foreach (str_split($request, 1048576) as $chunk) {
             $client->send($chunk);
         }
     } else {
         $client->send($request);
     }
     $response = $client->recv();
     $client->close();
     if ($response === false) {
         return false;
     }
     $length = unpack('N', $response)[1];
     return unserialize(substr($response, -$length));
 }
Esempio n. 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;
 }