groupManager = $groupManager ?? new GroupManager(); $this->websockets = new SplObjectStorage(); } public function addRoute(string $path, callable $handler, array $allowedOrigins=[]): void { } public function __invoke(ServerRequestInterface $request, callable $next) { if ($request->getHeaderLine('upgrade') !== 'websocket') { return $next($request); } $handshakeKey = trim($request->getHeaderLine('sec-websocket-key')); $handshakeResponse = base64_encode(sha1($handshakeKey.self::MAGIC,true)); // Create the streams we need to pass the websocket data back and forth. // This is returned with the response, and passed to the WebSocketConnection. $inStream = new ThroughStream(); $outStream = new ThroughStream(); $stream = new CompositeStream($outStream, $inStream); $websocket = new WebSocketConnection($request, $inStream, $outStream, $this->groupManager); $this->websockets->attach($websocket); $websocket->on('close', function () use ($websocket) { $this->websockets->detach($websocket); }); Loop::futureTick(function () use ($websocket) { $this->emit('connect', [ $websocket ]); }); return new Response( Response::STATUS_SWITCHING_PROTOCOLS, array( 'Upgrade' => 'websocket', 'Connection' => 'upgrade', 'Sec-WebSocket-Accept' => $handshakeResponse ), $stream ); } // private function hexdump($data): void // { // printf("%4d .\n", strlen($data)); // $rows = str_split($data, 16); // $offs = 0; // foreach ($rows as $row) { // $h = []; $a = []; // for ($n = 0; $n < 16; $n++) { // if ($n < strlen($row)) { // $h[] = sprintf("%02x%s", ord($row[$n]), ($n==7)?" ":" "); // $a[] = sprintf("%s%s", (ctype_print($row[$n])?$row[$n]:"."), ($n==7)?" ":""); // } else { // $h[] = (($n==7)?" ":" "); // $a[] = (($n==7)?" ":" "); // } // } // printf("%04x | %s | %s\n", 16 * $offs++, join("", $h), join("", $a)); // } // } }