python模擬websocket握手過程中計算sec-websocket-accept


背景

以前,很多網站使用輪詢實現推送技術。輪詢是在特定的的時間間隔(比如1秒),由瀏覽器對服務器發出HTTP request,然后由服務器返回最新的數據給瀏覽器。輪詢的缺點很明顯,瀏覽器需要不斷的向服務器發出請求,然而HTTP請求的header是非常長 的,而實際傳輸的數據可能很小,這就造成了帶寬和服務器資源的浪費。

Comet使用了AJAX改進了輪詢,可以實現雙向通信。但是Comet依然需要發出請求,而且在Comet中,普遍采用了長鏈接,這也會大量消耗服務器帶寬和資源。

於是,WebSocket協議應運而生。

WebSocket協議

瀏覽器通過 JavaScript 向服務器發出建立 WebSocket 連接的請求,連接建立以后,客戶端和服務器通過 TCP 連接直接交換數據。WebSocket 連接本質上是一個 TCP 連接。

WebSocket在數據傳輸的穩定性和數據傳輸量的大小方面,具有很大的性能優勢。Websocket.org 比較了輪詢和WebSocket的性能優勢:

從上圖可以看出,WebSocket具有很大的性能優勢,流量和負載增大的情況下,優勢更加明顯。

例子

瀏覽器請求

GET / HTTP/1.1 Upgrade: websocket Connection: Upgrade Host: example.com Origin: null Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ== Sec-WebSocket-Version: 13 

服務器回應

HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s= Sec-WebSocket-Origin: null Sec-WebSocket-Location: ws://example.com/ 

在請求中的Sec-WebSocket-Key是隨機的,服務器端會用這些數據來構造出一個SHA-1的信息摘要。把Sec-WebSocket-Key加上一個魔幻字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11。使用 SHA-1 加密,之后進行 BASE-64編碼,將結果作為 Sec-WebSocket-Accept 頭的值,返回給客戶端。

python代碼實現

def ws_accept_key(ws_key):
    """calc the Sec-WebSocket-Accept key by Sec-WebSocket-key
    come from client, the return value used for handshake

    :ws_key: Sec-WebSocket-Key come from client
    :returns: Sec-WebSocket-Accept

    """
    import hashlib
    import base64
    try:
        magic = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
        sha1 = hashlib.sha1()
        sha1.update(ws_key + magic)
        return base64.b64encode(sha1.digest())
    except Exception as e:
        return None
print ws_accept_key('sN9cRrP/n9NdMgdcy2VJFQ==')

 


免責聲明!

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



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