python模拟websocket握手过程中计算sec-websocket-accept
Posted godjob
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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==‘)
以上是关于python模拟websocket握手过程中计算sec-websocket-accept的主要内容,如果未能解决你的问题,请参考以下文章
WebSocket python服务器和JS客户端的握手错误
WebSockets Tutorial(教程一)————WebSockets简介