Websockets 握手问题

1 投票
1 回答
3827 浏览
提问于 2025-04-16 21:57

我在Python中创建了一个WebSocket服务器(基于这个代码片段),在本地运行得很好,但在生产服务器上却不行。

比如,在本地我看到的握手消息是这样的:

//Message from webbrowser client

GET / HTTP/1.1
Upgrade: WebSocket
Connection: Upgrade
Host: 127.0.0.1:8080
Origin: null
Sec-WebSocket-Key1: ]2 415       401   032v
Sec-WebSocket-Key2: 2y7   9Y2o 80049 5
Cookie: (...)

t��t`��


//Response of server

HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
WebSocket-Origin: null
WebSocket-Location: ws://127.0.0.1:8080/
Sec-Websocket-Origin: null
Sec-Websocket-Location: ws://127.0.0.1:8080/

�@2�J��3@5��ƶ

但是当我在生产环境中运行同样的WebSocket服务器时,连接失败了。在Chrome的控制台中,我看到以下错误信息:“WebSocket握手时出错:'Connection'头的值不是'Upgrade'”。不过在服务器和客户端之间的握手消息中,服务器发出的连接值是正确的:

//Message from webbrowser client

GET / HTTP/1.0
Host: myserver.com
X-Forwarded-Host: myserver.com
X-Forwarded-Server: myserver.com
X-Forwarded-For: 189.6.133.224
Connection: close
Upgrade: WebSocket
Origin: http://myserver.com
Sec-WebSocket-Key1: 2 1)Gz 11919la 978
Sec-WebSocket-Key2: c94Q6b9^ef#`6 2v {652
Cookie: (...)


//Response of server

HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
WebSocket-Origin: http://myserver.com
WebSocket-Location: ws://myserver.com/websocket/server
Sec-Websocket-Origin: http://myserver.com
Sec-Websocket-Location: ws://myserver.com/websocket/server

yz�~�r}��+�4J

在生产环境中,我在客户端的消息中看到了一些奇怪的值:

  • 消息末尾的那些奇怪代码是什么?
  • 'Connection'头的值竟然是'close'?!

有人知道为什么会出现这个错误,以及为什么客户端的握手消息会有这些值吗?

1 个回答

3
  • 消息末尾的那些奇怪代码是什么?

在客户端握手的最后,有8个原始字节,这实际上是第三个关键值。服务器返回的16个原始字节是从客户端握手中的三个关键值生成的摘要。这就是当前Hixie-76协议中摘要的工作原理。在即将发布的新的IETF/HyBi版本协议中,摘要机制不再使用特殊的原始字节了。

  • 为什么'Connection'头的值设置为'close'?

我觉得可能是有一个中间人(比如网络代理或透明代理)在修改客户端的握手信息,让它在到达服务器之前就变了。不仅是Connection头出错,客户端的握手中也缺少了第三个关键值。实际上,HyBi版本协议使用不同的摘要机制,就是为了更好地与这些中间人兼容。

建议

如果你的客户端和服务器在同一个网络上,并且你在Chrome中设置了代理,可以尝试暂时禁用代理,看看这样是否有效。

如果客户端和服务器不在同一个网络,但你可以控制同一网络上的两台机器,可以尝试在一台上运行客户端,在另一台上运行服务器(并确保Chrome中没有代理设置)。这样可以排除透明代理或中间人干扰握手的可能性。

如果你确定是Chrome的问题,而不是中间人的问题,可以通过在客户端运行wireshark来检查连接时实际发送的数据包。如果Chrome确实发送了那个确切的握手,那么可能是你的配置触发了Chrome的一个bug。

撰写回答