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 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM