Devristo\Phpws\Framing\WebSocketFrame::decode PHP Method

decode() public static method

public static decode ( &$buffer )
    public static function decode(&$buffer)
    {
        if (strlen($buffer) < 2) {
            return null;
        }
        $frame = new self();
        // Read the first two bytes, then chop them off
        $firstByte = substr($buffer, 0, 1);
        $secondByte = substr($buffer, 1, 1);
        $raw = substr($buffer, 2);
        $firstByte = ord($firstByte);
        $secondByte = ord($secondByte);
        $frame->FIN = self::IsBitSet($firstByte, 7);
        $frame->RSV1 = self::IsBitSet($firstByte, 6);
        $frame->RSV2 = self::IsBitSet($firstByte, 5);
        $frame->RSV3 = self::IsBitSet($firstByte, 4);
        $frame->mask = self::IsBitSet($secondByte, 7);
        $frame->opcode = $firstByte & 0xf;
        $len = $secondByte & ~128;
        if ($len <= 125) {
            $frame->payloadLength = $len;
        } elseif ($len == 126 && strlen($raw) >= 2) {
            $arr = unpack("nfirst", $raw);
            $frame->payloadLength = array_pop($arr);
            $raw = substr($raw, 2);
        } elseif ($len == 127 && strlen($raw) >= 8) {
            list(, $h, $l) = unpack('N2', $raw);
            $frame->payloadLength = $l + $h * 0x100000000;
            $raw = substr($raw, 8);
        } else {
            return null;
        }
        // If the frame is masked, try to eat the key from the buffer. If the buffer is insufficient, return null and
        // try again next time
        if ($frame->mask) {
            if (strlen($raw) < 4) {
                return null;
            }
            $frame->maskingKey = substr($raw, 0, 4);
            $raw = substr($raw, 4);
        }
        // Don't continue until we have a full frame
        if (strlen($raw) < $frame->payloadLength) {
            return null;
        }
        $packetPayload = substr($raw, 0, $frame->payloadLength);
        // Advance buffer
        $buffer = substr($raw, $frame->payloadLength);
        if ($frame->mask) {
            $frame->payloadData = self::rotMask($packetPayload, $frame->maskingKey, 0);
        } else {
            $frame->payloadData = $packetPayload;
        }
        return $frame;
    }

Usage Example

 public function handleData(&$data)
 {
     if (!$this->connected) {
         $data = $this->readHandshakeResponse($data);
     }
     $frames = array();
     while ($frame = WebSocketFrame::decode($data)) {
         if (WebSocketOpcode::isControlFrame($frame->getType())) {
             $this->processControlFrame($frame);
         } else {
             $this->processMessageFrame($frame);
         }
         $frames[] = $frame;
     }
     return $frames;
 }