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;
}