我正在尝试学习套接字编程以及WebSocket协议。我知道已经存在Python WebSocket客户端,但我希望为自己的学习构建一个玩具版本。为此,我创建了一个非常简单的Tornado WebSocket服务器,我正在localhost:8888
上运行它。它的全部作用就是在客户端连接时打印一条消息。
这就是整个服务器 - 它可以工作(我已经用浏览器中的小javascript脚本进行了测试)。
import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web
class WSHandler(tornado.websocket.WebSocketHandler):
def open(self):
print('new connection')
self.write_message("Hello World")
def on_message(self, message):
print('message received %s' % message)
def on_close(self):
print('connection closed')
application = tornado.web.Application([
(r'/ws', WSHandler),
])
if __name__ == "__main__":
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8888)
tornado.ioloop.IOLoop.instance().start()
一旦我启动服务器,我就尝试运行以下脚本:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((socket.gethostbyname('localhost'), 8888))
msg = '''GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13'''.encode('ascii')
print(len(msg))
sent_count = sock.send(msg)
print('sent this many bytes:', sent_count)
recv_value = sock.recv(1)
print('recvieved:', recv_value)
我希望服务器按照RFC规定发送响应头,但sock.recv却一直等待。这让我认为服务器没有确认websocket的初始握手。这个握手也是根据RFC进行的。我知道websocket key应该是随机的,但我不认为这会导致服务器忽略握手(websocket key有效)。我想一旦我能够发起握手,就能解决其余的问题,所以我希望只是对websockets的工作方式或如何发送初始握手存在一些误解。