/**
  * @inheritDoc
  */
 public function __invoke(ObservableInterface $observable, ObserverInterface $observer, SchedulerInterface $scheduler = null)
 {
     return $observable->subscribe(new CallbackObserver(function ($data) use($observer) {
         while (strlen($data) > 0) {
             $frame = $this->frame;
             $frame->addBuffer($data);
             $data = "";
             if ($frame->isCoalesced()) {
                 $result = $this->validator->validateFrame($frame, $this->previousFrame);
                 if (0 !== $result) {
                     $observer->onError(new WebsocketErrorException($result));
                 }
                 $data = $frame->extractOverflow();
                 $frame->unMaskPayload();
                 $observer->onNext($frame);
                 if ($frame->getOpcode() < 3) {
                     $this->previousFrame = $this->frame;
                     if ($frame->isFinal()) {
                         $this->previousFrame = null;
                     }
                 }
                 $this->frame = new Frame();
             }
         }
     }, [$observer, 'onError'], [$observer, 'onCompleted']));
 }
示例#2
0
 public function onData($data, ContextInterface $context)
 {
     $overflow = '';
     $message = $context->getMessage() ?: $context->setMessage($this->newMessage());
     $frame = $context->getFrame() ?: $context->setFrame($this->newFrame());
     $frame->addBuffer($data);
     if ($frame->isCoalesced()) {
         $frameCount = $message->count();
         $prevFrame = $frameCount > 0 ? $message[$frameCount - 1] : null;
         $frameStatus = $this->validator->validateFrame($frame, $prevFrame);
         if (0 !== $frameStatus) {
             return $context->onClose($frameStatus);
         }
         $opcode = $frame->getOpcode();
         if ($opcode > 2) {
             switch ($opcode) {
                 case Frame::OP_PING:
                     $context->onPing($frame);
                     break;
                 case Frame::OP_PONG:
                     $context->onPong($frame);
                     break;
             }
             $overflow = $frame->extractOverflow();
             $context->setFrame(null);
             if (strlen($overflow) > 0) {
                 $this->onData($overflow, $context);
             }
             return;
         }
         $overflow = $frame->extractOverflow();
         $frame->unMaskPayload();
         $message->addFrame($frame);
         $context->setFrame(null);
     }
     if ($message->isCoalesced()) {
         $msgCheck = $this->validator->checkMessage($message);
         if (true !== $msgCheck) {
             return $context->onClose($msgCheck);
         }
         $context->onMessage($message);
         $context->setMessage(null);
     }
     if (strlen($overflow) > 0) {
         $this->onData($overflow, $context);
     }
 }