public function writer(InternalRequest $ireq) : \Generator { $client = $ireq->client; $id = $ireq->streamId; $headers = yield; unset($headers[":reason"], $headers["connection"]); // obsolete in HTTP/2.0 $headers = HPack::encode($headers); // @TODO decide whether to use max-frame size if (\strlen($headers) > 16384) { $split = str_split($headers, 16384); $headers = array_shift($split); $this->writeFrame($client, $headers, self::HEADERS, self::NOFLAG, $id); $headers = array_pop($split); foreach ($split as $msgPart) { $this->writeFrame($client, $msgPart, self::CONTINUATION, self::NOFLAG, $id); } $this->writeFrame($client, $headers, self::CONTINUATION, self::END_HEADERS, $id); } else { $this->writeFrame($client, $headers, self::HEADERS, self::END_HEADERS, $id); } $msgs = ""; while (($msgPart = yield) !== null) { $msgs .= $msgPart; if ($msgPart === false || \strlen($msgs) > $client->options->outputBufferSize) { $this->writeData($client, $msgs, $id, false); $msgs = ""; } if ($client->isDead) { if (!$client->bufferPromisor) { $client->bufferPromisor = new Deferred(); $client->bufferPromisor->fail(new ClientException()); } while (true) { yield; } } } $this->writeData($client, $msgs, $id, true); if ($client->isDead && !$client->bufferPromisor) { $client->bufferPromisor = new Failure(new ClientException()); } if ($client->bufferPromisor) { $keepAlives =& $client->remainingKeepAlives; // avoid cyclic reference $client->bufferPromisor->when(static function () use(&$keepAlives) { $keepAlives++; }); } else { $client->remainingKeepAlives++; } }