python websocket handshake (RFC 6455)



我正在尝试使用RFC 6455协议在python上实现一个简单的websoket服务器。我从这里和这里采用了握手格式。

我正在使用Chromium 17和Firefox 11作为客户端,并收到此错误:

Uncaught Error: INVALID_STATE_ERR: DOM Exception 11

我希望在我的浏览器中看到hello from server,在服务器日志中看到hello from client

我想我的握手是错误的,你能指出我的错误吗?

##Server 日志,请求:

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 127.0.0.1:8999
Origin: null
Sec-WebSocket-Key: 8rYWWxsBPEigeGKDRNOndg==
Sec-WebSocket-Version: 13

##Server 日志,响应:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 3aDXXmPbE5e9i08zb9mygfPlCVw=

##Raw 字符串响应:

HTTP/1.1 101 Switching ProtocolsrnUpgrade: websocketrnConnection: UpgradernSec-WebSocket-Accept: 3aDXXmPbE5e9i08zb9mygfPlCVw=rnrn

##Server 代码:

import socket
import re
from base64 import b64encode
from hashlib import sha1
websocket_answer = (
    'HTTP/1.1 101 Switching Protocols',
    'Upgrade: websocket',
    'Connection: Upgrade',
    'Sec-WebSocket-Accept: {key}rnrn',
)
GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 8999))
s.listen(1)
client, address = s.accept()
text = client.recv(1024)
print text
key = (re.search('Sec-WebSocket-Key:s+(.*?)[nr]+', text)
    .groups()[0]
    .strip())
response_key = b64encode(sha1(key + GUID).digest())
response = 'rn'.join(websocket_answer).format(key=response_key)
print response
client.send(response)
print client.recv(1024)
client.send('hello from server')

##Client 代码:

<!DOCTYPE html>
<html>
<head>
    <title>test</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <script type="text/javascript">
        var s = new WebSocket('ws://127.0.0.1:8999');
        s.onmessage = function(t){alert(t)};
        s.send('hello from client');
    </script>
</head>
<body>
</body>
</html>

您的服务器握手代码看起来不错。

但是,客户端代码看起来会尝试在(异步)握手完成之前发送消息。 您可以通过将消息发送到 websocket 的 onopen 方法来避免这种情况。

建立连接后,服务器不会以纯文本形式发送或接收消息。 有关详细信息,请参阅规范的数据框架部分。 (客户端代码可以忽略这一点,因为浏览器会为您处理数据成帧。

我正在尝试同样的事情,但永远无法让它工作。最后,我找到了一篇由Aymeric Augustin撰写的文章《用于在Python中构建WebSocket服务器和客户端的库》。他这样做的方式(下面的代码)会自动为你握手。

import asyncio
import websockets
async def echo(websocket, path):
    async for message in websocket:
        await websocket.send(message)
asyncio.get_event_loop().run_until_complete(websockets.serve(echo, 'localhost', 8765))
asyncio.get_event_loop().run_forever()

最新更新