Exemplo n.º 1
0
 /**
  * Coroutine that handles incoming WebSocket frames.
  */
 protected function processIncomingFrames() : \Generator
 {
     $e = null;
     try {
         while (true) {
             $frame = (yield from $this->readNextFrame());
             if ($frame->isControlFrame()) {
                 if (!(yield from $this->handleControlFrame($frame))) {
                     break;
                 }
             } else {
                 switch ($frame->opcode) {
                     case Frame::TEXT:
                         yield from $this->handleTextFrame($frame);
                         break;
                     case Frame::BINARY:
                         yield from $this->handleBinaryFrame($frame);
                         break;
                     case Frame::CONTINUATION:
                         yield from $this->handleContinuationFrame($frame);
                         break;
                 }
             }
         }
     } catch (\Throwable $e) {
         $this->messages->close($e);
     } finally {
         $this->messages->close();
         try {
             foreach ($this->pings as $defer) {
                 $defer->fail($e ?? new \RuntimeException('WebSocket connection closed'));
             }
         } finally {
             $this->pings = [];
         }
         try {
             if ($this->socket->isAlive()) {
                 $reason = $e === null || $e->getCode() === 0 ? Frame::NORMAL_CLOSURE : $e->getCode();
                 (yield $this->writer->sendFrame(new Frame(Frame::CONNECTION_CLOSE, \pack('n', $reason))));
             }
         } finally {
             if ($this->logger) {
                 $this->logger->debug('WebSocket connection to {peer} closed', ['peer' => $this->socket->getRemoteAddress()]);
             }
             $this->socket->close();
         }
     }
 }