the lines the client wrote, without their line end */ public array $written = []; public bool $closed = false; public function open(): void { $this->emit('open'); } /** The server says something: one frame (code + fields), or raw bytes. */ public function serverSays(string $code, string ...$fields): void { $this->emit('data', [$code . "\t" . implode("\t", $fields) . "\n"]); } public function serverBytes(string $bytes): void { $this->emit('data', [$bytes]); } public function write(string $bytes): void { foreach (explode("\n", rtrim($bytes, "\n")) as $line) { $this->written[] = $line; } } public function close(): void { if (!$this->closed) { $this->closed = true; $this->emit('close', ['closed']); } } /** @return list and forgets them */ public function take(): array { $lines = $this->written; $this->written = []; return $lines; } }