public function read($waitTime = 0, $waitMicroTime = 200000, $getFrame = false)
    {
        if (!\is_resource($this->socket) || \feof($this->socket)) {
            return null;
        }

        $read = [$this->socket];
        $write = null;
        $expect = null;

        if (0 === \stream_select($read, $write, $expect, $waitTime, $waitMicroTime)) {
            return false;
        }

        $firstByte = $this->socketRead(1);
        $frame = [];
        $firstByte = \ord($firstByte);
        $secondByte = \ord($this->socketRead(1));

        // First byte decoding
        $frame['fin'] = ($firstByte & 128) >> 7;
        $frame['rsv1'] = ($firstByte & 64) >> 6;
        $frame['rsv2'] = ($firstByte & 32) >> 5;
        $frame['rsv3'] = ($firstByte & 16) >> 4;
        $frame['opcode'] = ($firstByte & 15);

        // Second byte decoding
        $frame['mask'] = ($secondByte & 128) >> 7;
        $frame['len'] = ($secondByte & 127);

        // Get length of the frame
        if (126 === $frame['len']) {
            $frame['len'] = \unpack('n', $this->socketRead(2))[1];
        } elseif (127 === $frame['len']) {
            list($higher, $lower) = \array_values(\unpack('N2', $this->socketRead(8)));
            $frame['len'] = ($higher << 32) | $lower;
        }

        // Get the mask key if needed
        if (1 === $frame['mask']) {
            $frame['mask_key'] = $this->socketRead(4);
        }

        $frame['data'] = $this->socketRead($frame['len']);

        // Decode data if needed
        if (1 === $frame['mask']) {
            for ($i = 0; $i < $frame['len']; ++$i) {
                $frame['data'][$i] = \chr(\ord($frame['data'][$i]) ^ \ord($frame['mask_key'][$i % 4]));
            }
        }

        if ($getFrame) {
            return $frame;
        }

        return (string) $frame['data'];
    }