public function write($data): void
    {
        $rand = \random_int(0, 28);
        $frame = [
            'fin' => 1,
            'rsv1' => 0,
            'rsv2' => 0,
            'rsv3' => 0,
            'opcode' => 1, // We always send text
            'mask' => 1,
            'len' => \strlen($data),
            'mask_key' => \substr(\md5(\uniqid()), $rand, 4),
            'data' => $data,
        ];

        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 ($frame['len'] > 2 ** 16) {
            $len = 127;
        } elseif ($frame['len'] > 125) {
            $len = 126;
        } else {
            $len = $frame['len'];
        }

        $firstByte = ($frame['fin'] << 7) | (($frame['rsv1'] << 7) >> 1) | (($frame['rsv2'] << 7) >> 2) | (($frame['rsv3'] << 7) >> 3) | (($frame['opcode'] << 4) >> 4);
        $secondByte = ($frame['mask'] << 7) | (($len << 1) >> 1);

        $this->socketWrite(\chr($firstByte));
        $this->socketWrite(\chr($secondByte));

        if (126 === $len) {
            $this->socketWrite(\pack('n', $frame['len']));
        } elseif (127 === $len) {
            $higher = $frame['len'] >> 32;
            $lower = ($frame['len'] << 32) >> 32;
            $this->socketWrite(\pack('N', $higher));
            $this->socketWrite(\pack('N', $lower));
        }

        if (1 === $frame['mask']) {
            $this->socketWrite($frame['mask_key']);
        }

        $this->socketWrite($frame['data']);
    }