/** * {@inheritdoc} */ public function sendBinary(ReadableStream $stream, int $priority = 0) : Awaitable { return $this->writer->execute(function () use($stream) { $type = Frame::BINARY; $reserved = Frame::RESERVED1; $context = $this->deflate->getCompressionContext(); $len = 0; try { $chunk = (yield $stream->readBuffer(4092)); while (null !== ($next = (yield $stream->readBuffer(4092)))) { $chunk = \deflate_add($context, $chunk, \ZLIB_SYNC_FLUSH); $len += (yield $this->writeFrame(new Frame($type, $chunk, false, $reserved))); $chunk = $next; $type = Frame::CONTINUATION; $reserved = 0; } if ($chunk !== null) { $chunk = \substr(\deflate_add($context, $chunk, $this->deflate->getCompressionFlushMode()), 0, -4); $len += (yield $this->writeFrame(new Frame($type, $chunk, true, $reserved))); } return $len; } finally { $stream->close(); } }, $priority); }
/** * Negotiate permessage-deflate WebSocket extensio if supported by the clientn. * * @param HttpRequest $request * @return PerMessageDeflate Or null when not supported by client / server or invalid window sizes are specified. */ protected function negotiatePerMessageDeflate(HttpRequest $request) { static $zlib; $extension = null; if ($zlib ?? ($zlib = \function_exists('inflate_init'))) { foreach ($request->getHeaderTokens('Sec-WebSocket-Extensions') as $ext) { if (\strtolower($ext->getValue()) === 'permessage-deflate') { $extension = $ext; break; } } } if ($extension === null) { return; } try { return PerMessageDeflate::fromHeaderToken($extension); } catch (\OutOfRangeException $e) { return; } }
/** * Enable permessage-deflate WebSocket protocol extension. * * @param PerMessageDeflate $deflate */ public function enablePerMessageDeflate(PerMessageDeflate $deflate) { $this->deflate = $deflate; $this->writer = new CompressedMessageWriter($this->socket, $this->client, $deflate); if ($this->logger) { $this->logger->debug('Enabled extension: {extension}', ['extension' => $deflate->getExtensionHeader()]); } }