PHP使用websocket的升级协议、解帧、封帧

35阅读-0评论-作者:码农 websocket socket PHP 聊天室
我们使用PHP带的socket扩展开发聊天室的时候,很多人不会升级协议、解帧和封帧,下面我们就把这些东西写一下做个记录。

协议升级

    websocket链接到服务端以后需要把协议从http升级到websocket,这个时候我们就需要获取请求中的Sec-WebSocket-Key的值拿到,我们使用PHP自带的preg_match获取即可,代码如下

preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $buffer, $match)

里面的参数都是什么意思,我就不做讲解了。我们获取到这个Sec-WebSocket-Key后,组装响应完成升级,代码如下

preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $buffer, $match);

$responseKey = base64_encode(sha1($match[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));

$upgrade  = "HTTP/1.1 101 Switching Protocol\r\n" .
                    "Upgrade: websocket\r\n" .
                    "Connection: Upgrade\r\n" .
                    "Sec-WebSocket-Accept: " . $responseKey . "\r\n\r\n";

然后发送给客户端即可完成协议升级。

解帧

    public function decode($buffer)
    {
        $len = $masks = $data = $decoded = null;
        $len = ord($buffer[1]) & 127;

        if ($len === 126) {
            $masks = substr($buffer, 4, 4);
            $data = substr($buffer, 8);
        } elseif ($len === 127) {
            $masks = substr($buffer, 10, 4);
            $data = substr($buffer, 14);
        } else {
            $masks = substr($buffer, 2, 4);
            $data = substr($buffer, 6);
        }
        for ($index = 0; $index < strlen($data); $index++) {
            $decoded .= $data[$index] ^ $masks[$index % 4];
        }
        return $decoded;
    }

封帧

    public function frame($message)
    {
        $len = strlen($message);
        if ($len <= 125) {
            return "\x81" . chr($len) . $message;
        } else if ($len <= 65535) {
            return "\x81" . chr(126) . pack("n", $len) . $message;
        } else {
            return "\x81" . char(127) . pack("xxxxN", $len) . $message;
        }
    }



代码具体什么意思,这里就不再做过多的讲解了,相信大家也是可以看明白的。


QQ:1007027975

0.067658s