resolve(new self($socket)); }); $timer = Loop::delay($timeout, function () use ($deferred, $watcher, $uri) { Loop::cancel($watcher); $deferred->fail(new TimeoutException("Name resolution timed out, could not connect to server at $uri")); }); return $deferred->promise(); } public static function parser(callable $callback) { $decoder = (new DecoderFactory)->create(); $length = \unpack("n", yield 2)[1]; $callback($decoder->decode(yield $length)); } protected function __construct($socket) { parent::__construct($socket); $this->encoder = (new EncoderFactory)->create(); $this->queue = new \SplQueue; $this->parser = new Parser(self::parser([$this->queue, 'push'])); } public function send(Message $message): Promise { $data = $this->encoder->encode($message); return $this->write(\pack("n", \strlen($data)) . $data); } public function receive(): Promise { if ($this->queue->isEmpty()) { return call(function () { do { $chunk = $this->read(); if ($chunk === null) { throw new ResolutionException("Reading from the server failed"); } $this->parser->push($chunk); } while ($this->queue->isEmpty()); return $this->queue->shift(); }); } return new Success($this->queue->shift()); } }