/** * {@inheritdoc} */ public function upgradeConnection(SocketStream $socket, HttpRequest $request, HttpResponse $response) : \Generator { $endpoint = $response->getAttribute(Endpoint::class); if (!$endpoint instanceof Endpoint) { throw new \InvalidArgumentException('No endpoint object passed to WebSocket handler'); } if ($this->logger) { $this->logger->debug('HTTP/{protocol} connection from {peer} upgraded to WebSocket', ['protocol' => $request->getProtocolVersion(), 'peer' => $socket->getRemoteAddress()]); } $conn = new Connection($socket, false, $response->getHeaderLine('Sec-WebSocket-Protocol')); if ($this->logger) { $conn->setLogger($this->logger); } if ($deflate = $response->getAttribute(PerMessageDeflate::class)) { $conn->enablePerMessageDeflate($deflate); } yield from $this->delegateToEndpoint($conn, $endpoint); }
/** * Establish a WebSocket connection using the given handshake HTTP response. * * @param string $location * @param HttpResponse $response * @return Connection */ protected function establishConnection(string $location, HttpResponse $response) : Connection { $socket = $response->getAttribute(SocketStream::class); if (!$socket instanceof SocketStream) { throw new \RuntimeException('Failed to access HTTP socket stream via response attribute'); } try { $conn = new Connection($socket, true, $response->getHeaderLine('Sec-WebSocket-Protocol')); if ($this->logger) { $conn->setLogger($this->logger); $this->logger->debug('Established WebSocket connection to {peer} ({uri})', ['peer' => $socket->getRemoteAddress(), 'uri' => $location]); } if ($deflate = $this->negotiatePerMessageDeflate($response)) { if (!$this->deflateSupported) { throw new \RuntimeException('Server enabled permessage-deflate but client does not support the extension'); } $conn->enablePerMessageDeflate($deflate); } return $conn; } catch (\Throwable $e) { $socket->close(); throw $e; } }