Пример #1
0
 private function readLoop() : Generator
 {
     try {
         while ($this->state === ConnectionState::OPEN) {
             $frame = (yield $this->transport->read());
             $this->heartbeatsSinceFrameReceived = 0;
             if ($frame instanceof HeartbeatFrame) {
                 continue;
             } elseif ($frame->frameChannelId > 0) {
                 $channelManager = $this->channels[$frame->frameChannelId] ?? null;
                 if ($channelManager === null) {
                     throw ProtocolException::unexpectedFrame($frame, \sprintf('channel #%s is closed', $frame->frameChannelId));
                 }
                 (yield $channelManager->dispatch($frame));
             } elseif ($frame instanceof ConnectionCloseFrame) {
                 (yield $this->transport->close());
                 throw AmqpException::create($frame->replyText, $frame->replyCode);
             } else {
                 throw ProtocolException::unexpectedFrame($frame, 'received on channel #0');
             }
         }
         while ($this->state === ConnectionState::CLOSING) {
             $frame = (yield $this->transport->read());
             if ($frame instanceof ConnectionCloseOkFrame) {
                 (yield $this->transport->close());
                 (yield $this->onClose());
             }
         }
     } catch (ChannelClosedException $e) {
         (yield $this->onClose(SingleConnectionException::closedUnexpectedly($this->options, $e)));
     } catch (Throwable $e) {
         assert(Debug::dumpException('read-loop', $e));
         (yield $this->onClose($e));
     }
 }
Пример #2
0
 /**
  * @recoil-coroutine
  */
 public function onCloseByBroker(ChannelCloseFrame $frame) : Generator
 {
     $this->connectionManager->removeChannel($this->channelId);
     $exception = AmqpException::create($frame->replyText, $frame->replyCode);
     // The closure was triggered by a previously sent frame. Find the
     // offending strand and resume it with an exception specific to this
     // closure ...
     if ($frame->classId && $frame->methodId) {
         $sentMethod = $frame->classId << 16 | $frame->methodId;
         ($callers =& $this->callersBySentMethod[$sentMethod]) ?? null;
         if ($callers !== null) {
             foreach ($callers as $id => $waitMethod) {
                 $strand = $this->callers[$waitMethod][$id];
                 unset($this->callers[$waitMethod][$id], $this->callersBySentMethod[$sentMethod][$id], $this->callersByWaitMethod[$waitMethod][$id]);
                 (yield Recoil::throw($strand, $exception));
                 break;
             }
         }
     }
     // Acknowledge the closure ...
     $frame = new ChannelCloseOkFrame();
     $frame->frameChannelId = $this->channelId;
     (yield $this->transport->write($frame));
     // Procee to the regular on-close logic. To all remaining callers and
     // listeners this is an unexpected closure ...
     (yield $this->onClose(ChannelException::closedUnexpectedly($this->channelId, $exception)));
 }