/** * Start & init the API */ public function listen() { // Init API $this->apiManager->init(); if (!$this->apiManager->connect()) { throw new \RuntimeException('There is no ready client, aborted'); } // Init server $loop = $this->apiManager->getLoop(); $socket = new SocketServer($loop); $socket->on('connection', function ($conn) { /** @var Connection $conn */ $this->logger->debug(sprintf('Client [%s] is connected to server', $conn->getRemoteAddress())); // On receive data $conn->on('data', function ($rawData) use($conn) { $this->logger->debug(sprintf('Client sent: %s', $rawData)); $data = json_decode($rawData, true); $format = null; if (isset($data['format'])) { $format = $data['format']; } try { if (!$this->isValidInput($data)) { throw new MalformedClientInputException('The input sent to the server is maformed'); } $conn->on('api-response', function ($response) use($conn, $format) { $conn->end($this->format($response, $format)); }); $conn->on('api-error', function (ServerException $e) use($conn, $format) { $conn->end($this->format($e->toArray(), $format)); if ($e instanceof RequestTimeoutException) { $e->getClient()->reconnect(); // Force doing heartbeats to check if another client is timed out $this->apiManager->doHeartbeats(); } }); $this->apiManager->getRouter()->process($this->apiManager, $conn, $data); } catch (ServerException $e) { $this->logger->error('Client [' . $conn->getRemoteAddress() . ']: ' . $e->getMessage()); $conn->end($this->format($e->toArray(), $format)); } }); }); $port = ConfigurationLoader::get('server.port'); $bind = ConfigurationLoader::get('server.bind'); $this->logger->info(sprintf('Listening on %s:%d', $bind == '0.0.0.0' ? '*' : $bind, $port)); $socket->listen($port, $bind); $loop->run(); }
/** * @param null|callable $callback This callback will format the results array */ protected function sendResponse(\Closure $callback = null) { $this->apiManager->getLoop()->addPeriodicTimer(0.0001, function (TimerInterface $timer) use($callback) { if ($this->hasError) { $timer->cancel(); return; } if (0 < $this->invokeCount && $this->invokeCount == $this->responseCount) { // Convert indexed array to associative if count = 1 if (isset($this->results[0]) && !isset($this->results[1])) { $this->results = $this->results[0]; } $this->conn->emit('api-response', [['success' => true, 'result' => null != $callback ? $callback($this->results) : $this->results]]); $timer->cancel(); } }); }