protected function sendAndReceive($request, stdClass $context) { $future = new Future(); $id = $this->getNextId(); $count =& $this->count; $futures =& $this->futures; $futures[$id] = $future; if ($context->timeout > 0) { $timeoutFuture = new Future(); $timer = swoole_timer_after($context->timeout, function () use($timeoutFuture) { $timeoutFuture->reject(new TimeoutException('timeout')); }); $future->whenComplete(function () use($timer) { swoole_timer_clear($timer); })->fill($timeoutFuture); $future = $timeoutFuture->catchError(function ($e) use(&$count, &$futures, $id) { unset($futures[$id]); --$count; throw $e; }, function ($e) { return $e instanceof TimeoutException; }); } if (!$this->connecting && ($this->ws === null || !$this->ws->isConnected())) { $this->connect(); } $ws = $this->ws; if ($count < 100) { ++$count; $this->ready->then(function () use($ws, $id, $request, &$futures) { $data = pack('N', $id) . $request; if ($ws->push($data, WEBSOCKET_OPCODE_BINARY, true) === false) { if (isset($futures[$id])) { $error = new Exception(socket_strerror($ws->errCode)); $futures[$id]->reject($error); } } }); } else { $this->requests[] = array($id, $request); } if ($context->oneway) { $future->resolve(null); } return $future; }