PHPDaemon\Servers\WebSocket\Protocols\V13::onRead PHP Method

onRead() public method

Called when new data received
See also: http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10#page-16
public onRead ( ) : void
return void
    public function onRead()
    {
        if ($this->state === self::STATE_PREHANDSHAKE) {
            if (!$this->handshake()) {
                return;
            }
        }
        if ($this->state === self::STATE_HANDSHAKED) {
            while (($buflen = $this->getInputLength()) >= 2) {
                $first = ord($this->look(1));
                // first byte integer (fin, opcode)
                $firstBits = decbin($first);
                $opcode = (int) bindec(substr($firstBits, 4, 4));
                if ($opcode === 0x8) {
                    // CLOSE
                    $this->finish();
                    return;
                }
                $opcodeName = isset(static::$opcodes[$opcode]) ? static::$opcodes[$opcode] : false;
                if (!$opcodeName) {
                    Daemon::log(get_class($this) . ': Undefined opcode ' . $opcode);
                    $this->finish();
                    return;
                }
                $second = ord($this->look(1, 1));
                // second byte integer (masked, payload length)
                $fin = (bool) ($first >> 7);
                $isMasked = (bool) ($second >> 7);
                $dataLength = $second & 0x7f;
                $p = 2;
                if ($dataLength === 0x7e) {
                    // 2 bytes-length
                    if ($buflen < $p + 2) {
                        return;
                        // not enough data yet
                    }
                    $dataLength = Binary::bytes2int($this->look(2, $p), false);
                    $p += 2;
                } elseif ($dataLength === 0x7f) {
                    // 8 bytes-length
                    if ($buflen < $p + 8) {
                        return;
                        // not enough data yet
                    }
                    $dataLength = Binary::bytes2int($this->look(8, $p));
                    $p += 8;
                }
                if ($this->pool->maxAllowedPacket <= $dataLength) {
                    // Too big packet
                    $this->finish();
                    return;
                }
                if ($isMasked) {
                    if ($buflen < $p + 4) {
                        return;
                        // not enough data yet
                    }
                    $mask = $this->look(4, $p);
                    $p += 4;
                }
                if ($buflen < $p + $dataLength) {
                    return;
                    // not enough data yet
                }
                $this->drain($p);
                $data = $this->read($dataLength);
                if ($isMasked) {
                    $data = $this->mask($data, $mask);
                }
                //Daemon::log(Debug::dump(array('ext' => $this->extensions, 'rsv1' => $firstBits[1], 'data' => Debug::exportBytes($data))));
                /*if ($firstBits[1] && in_array('deflate-frame', $this->extensions)) { // deflate frame
                      $data = gzuncompress($data, $this->pool->maxAllowedPacket);
                  }*/
                if (!$fin) {
                    $this->framebuf .= $data;
                } else {
                    $this->onFrame($this->framebuf . $data, $opcodeName);
                    $this->framebuf = '';
                }
            }
        }
    }