一、WebSocket Header概述
WebSocket是HTML5中一种新的协议,它实现了浏览器与服务器的全双工通信,使得客户端和服务器可以进行实时的数据传输。搭建WebSocket服务器,需要先了解WebSocket连接建立的过程中的头部信息。
二、WebSocket Header格式
在建立WebSocket连接时,浏览器和服务器之间会进行协议升级,即使用HTTP协议发起一个握手请求来升级连接。发起握手请求时,浏览器会在请求头中加上"Sec-WebSocket-Key"和"Sec-WebSocket-Version"这两个字段,服务器需要根据这两个字段来判断是否支持WebSocket协议,如支持则必须回应101状态码,并在响应头中加入"Upgrade"和"Connection"这两个字段。
GET /[path] HTTP/1.1 Host: [host] Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: [key] Sec-WebSocket-Version: [version]
"Sec-WebSocket-Key"是一个随机字符串,服务器需要使用这个字符串来加密后再转换成字节数组,然后通过SHA-1计算出20个字节的哈希值,最后将此哈希值的base64编码作为响应头中的"Sec-WebSocket-Accept"字段。
三、WebSocket Header字段解析
1. Upgrade
"Upgrade"是请求头中的一个字段,表示浏览器希望升级到哪种协议。在升级WebSocket时,其值为"websocket"。
2. Connection
"Connection"是请求头中的一个字段,表示浏览器希望建立的连接类型。在升级WebSocket时,其值为"Upgrade"。
3. Sec-WebSocket-Key
"Sec-WebSocket-Key"是浏览器生成的随机字符串,用于计算响应值。服务器需要将这个字符串与一个魔术字符串 "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" 拼接,然后计算 SHA1 哈希值。最后,服务器以 Base64 编码方式返回哈希值,并在响应头中添加"Sec-WebSocket-Accept"字段,告诉浏览器解码响应头并验证key是否正确。
4. Sec-WebSocket-Version
"Sec-WebSocket-Version"是请求头中的一个字段,表示浏览器支持的WebSocket协议版本号。
5. Sec-WebSocket-Accept
"Sec-WebSocket-Accept"是响应头中的一个字段,表示服务器计算出来的响应值,也就是经过base64编码后的字符串。这个值需要被浏览器验证,以确保握手请求是受信任的。
四、WebSocket Header参考代码
1. Python实现WebSocket握手过程
def handshake(sock): """ handshake for WebSocket """ data = sock.recv(1024) headers = {} lines = data.decode('utf-8').splitlines() for l in lines: parts = l.split(": ", 1) if len(parts) == 2: headers[parts[0]] = parts[1] headers['Sec-WebSocket-Accept'] = b64encode( sha1((headers['Sec-WebSocket-Key'] + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").encode('utf-8')).digest()) response = \ b"HTTP/1.1 101 Web Socket Protocol Handshake\r\n" \ b"Upgrade: websocket\r\n" \ b"Connection: Upgrade\r\n" \ b"Sec-WebSocket-Accept: " + headers['Sec-WebSocket-Accept'] + b"\r\n\r\n" sock.send(response)
2. JavaScript实现WebSocket握手过程
var socket = new WebSocket("ws://localhost:8080/"); socket.onopen = function() { var key = generateWebSocketKey(); var headers = { "Upgrade": "websocket", "Connection": "Upgrade", "Sec-WebSocket-Key": key, "Sec-WebSocket-Version": "13" }; socket.send(buildWebSocketHandshake(headers)); } function generateWebSocketKey() { var buffer = new Uint32Array(1); var bytes = new Uint8Array(buffer.buffer); window.crypto.getRandomValues(buffer); var key = ''; for (var byte of bytes) { key += String.fromCharCode(byte); } return btoa(key); } function buildWebSocketHandshake(headers) { var lines = []; for (var k in headers) { lines.push(k + ": " + headers[k]); } var handshake = "GET / HTTP/1.1\r\n" + lines.join("\r\n") + "\r\n\r\n"; return handshake; }
五、总结
WebSocket的Header信息是WebSocket建立连接的重要组成部分,其握手过程确保通信双方都能正常解析对方发来的信息。通过查看header信息,可以轻松了解WebSocket请求的详细内容,对于开发和调试WebSocket应用程序非常有帮助。