• websocket协议握手详解


    最近使用tornado做长链接想着怎么着也要试试websocket协议吧。所以说干就干。

    首先要知道websocket是基于http协议的,为什么这么说?因为从协议来说,websocket是借用了一部分为http请求头信息来进行验证和请求的的。

    让我们来看一个标准的websocket请求头:

    --- request header ---
    GET /chat HTTP/1.1
    Upgrade: websocket
    Connection: Upgrade
    Host: 127.0.0.1:8001
    Origin: http://127.0.0.1:8001
    Sec-WebSocket-Key: hj0eNqbhE/A0GkBXDRrYYw==
    Sec-WebSocket-Version: 13

    可以看到使用http1.1 协议上面是标准的http的请求信息

    method url http_protocol_versions
    Host
    Connection

    但是熟悉http的小伙伴可以明显看出这里多出了一些信息。用于实现协议升级

    
    
    Upgrade: websocket
    Connection: Upgrade
    origin:xxxx
    Sec-WebSocket-Key: hj0eNqbhE/A0GkBXDRrYYw==
    Sec-WebSocket-Version: 13

    upgrade websocket用于告诉服务器此连接需要升级到websocket。

    而下面的Sec-WebSocket-Key是客户端也就是浏览器或者其他终端随机生成一组16位的随机base64编码的串发上去这里贴上我在websocket-client 这个库里面找到的生成这个key的函数。

    def _create_sec_websocket_key():
        randomness = os.urandom(16)
        return base64encode(randomness).decode('utf-8').strip()

    最后Sec-WebSocket-Version就是当前使用协议的版本号了。

    服务器在接受到上面的请求之后,会返回一个response 头包完成握手。

    HTTP/1.1 101 Switching Protocols
    Content-Length: 0
    Upgrade: websocket
    Sec-Websocket-Accept: ZEs+c+VBk8Aj01+wJGN7Y15796g=
    Server: TornadoServer/4.5.1
    Connection: Upgrade
    Date: Wed, 21 Jun 2017 03:29:14 GMT

    由Sec-Websocket-Accept的key完成校验。 我贴一个生成的Sec-Websocket-Accept的代码大家感受一下

        def compute_accept_value(key):
            """Computes the value for the Sec-WebSocket-Accept header,
            given the value for Sec-WebSocket-Key.
            """
            sha1 = hashlib.sha1()
            sha1.update(utf8(key))
            sha1.update(b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11")  # Magic value
            return native_str(base64.b64encode(sha1.digest()))

    这个入参key就是客户端发上来的Sec_key。 然后服务器进行sha1计算并且拼上一个GUID RFC6455中可以找到这个字符串。然后进行base64encode返回给客户端。客户端拿到后拿自己的key做同样的加密,如果对得上握手完成。到此为止就可以开始愉快的使用websocket进行交流了!

    本文到这里就完了,如果要想了解websocket协议和传统的long poll 和 short poll 之间的区别和使用场景,可以看下reference中的第一条。说得非常详细和有趣。在本文就不赘述了。 

    Reference:

    https://www.zhihu.com/question/20215561  WebSocket是什么原理,为什么可以实现持久连接。

    https://tools.ietf.org/html/rfc6455  RFC6455 

  • 相关阅读:
    SVN版本控制服务
    JVM内存结构
    Git的使用
    Nginx详解
    Apache(httpd)详解
    rsyslog日志收集器
    nsswitch名称解析框架
    NFS网络文件系统
    ThreadLocal详解
    RocketMQ踩坑记
  • 原文地址:https://www.cnblogs.com/piperck/p/7058915.html
Copyright © 2020-2023  润新知