最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - python websocket handshake (RFC 6455) - Stack Overflow

programmeradmin3浏览0评论

I am trying to implement a simple websoket server on python, using RFC 6455 protocol. I took handshake format from here and here.

I am using Chromium 17 and Firefox 11 as clients, and getting this error:

Uncaught Error: INVALID_STATE_ERR: DOM Exception 11

I expect to see hello from server in my browser and hello from client in server log.

I guess my handshake is wrong, can you point me to my mistake?

##Server log, request:

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 log, response:

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

##Raw-string response:

HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: 3aDXXmPbE5e9i08zb9mygfPlCVw=\r\n\r\n

##Server code:

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}\r\n\r\n',
)

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+(.*?)[\n\r]+', text)
    .groups()[0]
    .strip())

response_key = b64encode(sha1(key + GUID).digest())
response = '\r\n'.join(websocket_answer).format(key=response_key)

print response
client.send(response)

print client.recv(1024)
client.send('hello from server')

##Client code:

<!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>

I am trying to implement a simple websoket server on python, using RFC 6455 protocol. I took handshake format from here and here.

I am using Chromium 17 and Firefox 11 as clients, and getting this error:

Uncaught Error: INVALID_STATE_ERR: DOM Exception 11

I expect to see hello from server in my browser and hello from client in server log.

I guess my handshake is wrong, can you point me to my mistake?

##Server log, request:

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 log, response:

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

##Raw-string response:

HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: 3aDXXmPbE5e9i08zb9mygfPlCVw=\r\n\r\n

##Server code:

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}\r\n\r\n',
)

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+(.*?)[\n\r]+', text)
    .groups()[0]
    .strip())

response_key = b64encode(sha1(key + GUID).digest())
response = '\r\n'.join(websocket_answer).format(key=response_key)

print response
client.send(response)

print client.recv(1024)
client.send('hello from server')

##Client code:

<!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>
Share Improve this question edited Oct 7, 2021 at 5:51 CommunityBot 11 silver badge asked Apr 14, 2012 at 8:50 John SmithJohn Smith 731 gold badge1 silver badge3 bronze badges 2
  • Unless it's for learning how it works I'd not implement websockets on my own. There are existing implementations such as code.google./p/pywebsocket – ThiefMaster Commented Apr 14, 2012 at 8:52
  • 4 it exactly for learning. I want to know and understand basics before start using libraries – John Smith Commented Apr 14, 2012 at 8:54
Add a ment  | 

2 Answers 2

Reset to default 5

Your server handshake code looks good.

The client code looks like it'll try to send a message before the (asynchronous) handshake pletes however. You could avoid this by moving your message send into your websocket's onopen method.

Once the connection is established, the server does not send or receive messages as plain text. See the data framing section of the spec for details. (Client code can ignore this as the browser takes care of data framing for you.)

I was trying the same thing, but could never get it working. In the end i found an article Library for building WebSocket servers and clients in Python by Aymeric Augustin. The way he does it (code below) does the handshake for you automatically.

import asyncio
import websockets

async def echo(websocket, path):
    async for message in websocket:
        await websocket.send(message)

asyncio.get_event_loop().run_until_plete(websockets.serve(echo, 'localhost', 8765))
asyncio.get_event_loop().run_forever()
发布评论

评论列表(0)

  1. 暂无评论