websocket协议 draft10

    我去,昨晚websocket还工作得好好的,今早就发现不能用了。检查了一圈发现原来是chrome升级到14后,支持的websocket协议改变了,不再是之前的76草案,改为支持draft-10草案了。从75草案开始,这已经是我知道的第三个握手协议方案了。google chrome团队的博客说,这应该是最后一次稳定的版本了,应该不会再改变了,可以将其应用到生产环境中:http://infra.sunway.dk/cms/fh3aggregator/sources/34#iid-189713

    另外几个可以看看的资料如下:

http://www.codeproject.com/KB/HTML/Web-Socket-in-Essence.aspx#BrowserSupport

http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10

     

    好吧,在safari跟上来以前,我还是将两种握手协议都封装一下吧。代码贴出来:

    def __handshakeHandler(self,data):

        response = ""

        if re.findall(r'Sec-WebSocket-Key: (.*)\n',data):

            key = re.findall(r'Sec-WebSocket-Key: (.*)\n',data)[0].strip()

            MAGIC_KEY = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" 

            token = base64.b64encode(hashlib.sha1(key+MAGIC_KEY).digest())

            response = '''

HTTP/1.1 101 Switching Protocols\r

Upgrade: websocket\r

Connection: Upgrade\r

Sec-WebSocket-Accept: %s\r\n\r

'''.lstrip() % token

        else:

            resource = re.compile("GET (.*) HTTP").findall(data)[0]

            host = re.compile("Host: (.*)\r\n").findall(data)[0]

            origin = re.compile("Origin: (.*)\r\n").findall(data)[0]

            num1 = re.findall(r'Sec-WebSocket-Key1: (.*)\n',data)[0]

            num2 = re.findall(r'Sec-WebSocket-Key2: (.*)\n',data)[0]

            key = re.findall(r'\r\n\r\n(.*)$',data)[0]

            num1_num = int("".join(re.findall(r'\d',num1)))

            num1_space = len(re.findall(r' ',num1))

            num2_num = int("".join(re.findall(r'\d',num2)))

            num2_space = len(re.findall(r' ',num2))

            token = "%s%s%s" % (struct.pack('>L',num1_num/num1_space),struct.pack('>L',num2_num/num2_space),key)

            token = hashlib.md5(token).digest()

            response = '''

HTTP/1.1 101 WebSocket Protocol Handshake\r

Upgrade: WebSocket\r

Connection: Upgrade\r

Sec-WebSocket-Origin: %s\r

Sec-WebSocket-Location: ws://%s/\r

Sec-WebSocket-Protocol: sample\r\n\r

%s'''.strip() % (origin,host,token)

        self.transport.write(response)



握手协议改好了就完了吗?NO!!!恶梦才刚开始,现在发送和接收数据也变了规则,新规则坑爹得很啊,看得我那个想死啊!!!

参考地址如下:http://blog.vunie.com/implementing-websocket-draft-10

好吧,终于用python写出了通信的代码,如下:

[ 接收消息 ] 

            if draftType == "76":

                data = data[1:-1]

            elif draftType == "10":

                if data[0] != "\x81": return

                length = int(binascii.b2a_hex(data[1]),16) & 0x7f 

                if length < 126:

                    mask = data[2:6]

                    text = data[6:]

                elif length == 126:

                    mask = data[4:8]

                    text = data[8:]

                elif length == 127:

                    mask = data[10:14]

                    text = data[14:]

                unMaskedText = ""

                for i,v in enumerate(text):

                    unMaskedText += binascii.a2b_hex(hex(int(binascii.b2a_hex(text[i]),16) ^ int(binascii.b2a_hex(mask[i%4]),16))[2:])

                data = unMaskedText

===================================================
[发送消息]

    response = ""

    if draftType == "76":

        response = '''\x00%s\xFF''' % str

    elif draftType == "10":

        token = "\x81"

        length = len(str)

        if length < 126:

            token += binascii.a2b_hex(hex(length)[2:])

        elif length < 65535:

            token += binascii.a2b_hex(hex(126)[2:])

            _a = hex(length>>8)[2:]

            if len(_a) % 2:

                _a = "0"+_a

            token += binascii.a2b_hex(_a)

            _b = hex(length & 0xff)[2:]

            if len(_b) % 2:

                _b = "0"+_b

            token += binascii.a2b_hex(_b)

        else:

            print "I don't know how to do T_T"

        response = '''%s%s''' % (token,str)


好吧,也许你也注意到了 “else:

print "I don't know how to do T_T"

” 

当需发送的字符串长度超过65535的时候,我们需要用8个字节来表示他的长度,而我在这里不知道如何处理了,因为参考的那篇博客里用的是nodejs,而且他没有讲到如何处理这种情况,所以我在这里不知道怎么办了。。。好在,一般情况下,我们是不会需要这么长的发送量的,我将一个二进制图片base64一下,长度也没超过,所以正常情况下,我们没有超过这个长度的可能性,先不处理也不要紧。



===================================================

更新:终于比较圆满地解决接收和发送消息了,具体方法更新在这里:http://hi.baidu.com/cly84920/blog/item/ad3979ec6ac2ab3b63d09fb2.html

原文地址:https://www.cnblogs.com/cly84920/p/4426572.html