我在做一个关于WebSocket协议的研究,并试图在后台使用
Python实现一个简单的ECHO服务.
它似乎工作正常,但建立后连接下降.
它似乎工作正常,但建立后连接下降.
这是我的客户:
<!doctype html> <head> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> function Client() { //var ws = new WebSocket("ws://echo.websocket.org"); // this works fine var ws = new WebSocket("ws://localhost:8000"); ws.onopen = function(e){ $("#response").append(">> Connected<br />"); } ws.onclose = function(e){ $("#response").append(">> Disconnected<br />"); } ws.onerror = function(e){ $("#response").append(">> ERROR: " + e.data + "<br />"); } ws.onmessage = function(e){ $("#response").append("> " + e.data + "<br />"); } this.sendCmd = function() { var message = $("#cmd").val(); $("#response").append(message + "<br />"); ws.send(message); return false; } this.disconnect = function() { ws.close(); } } // onload $(function() { $("#response").append(">> Connecting<br />"); client = new Client(); $("#send").click(client.sendCmd); $("#disconnect").click(client.disconnect); }); </script> </head> <body> <input type="text" name="cmd" id="cmd" /> | <a href="#" id="send">Send</a> | <a href="#" id="disconnect">Disconnect</a><br /> <hr /> <span id="response"></span> </body> </html>
这是服务器:
import SocketServer import socket from hashlib import sha1 from base64 import b64encode PORT = 8000 MAGIC = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" class Handler(SocketServer.BaseRequestHandler): # incoming connection def setup(self): self.data = self.request.recv(1024).strip() print "connection established",self.client_address self.headers = self.headsToDict(self.data.split("\n")) # incoming message def handle(self): # its a handshake if "Upgrade" in self.headers and self.headers["Upgrade"] == "websocket": key = self.headers["Sec-WebSocket-Key"] accept = b64encode(sha1(key + MAGIC).hexdigest().decode('hex')) response = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" # "HTTP/1.1 101 Switching Protocols\r\n" print "< HTTP/1.1 101 Web Socket Protocol Handshake" # "HTTP/1.1 101 Switching Protocols\r\n" response += "Upgrade: websocket\r\n" print "< Upgrade: websocket" response += "Connection: Upgrade\r\n" print "< Connection: Upgrade" response += "Sec-WebSocket-Accept: "+accept+"\r\n\r\n" print "< Sec-WebSocket-Accept: "+accept self.request.send(response) # its a normal message,echo it back else: print self.data self.request.send(self.data) # connection dropped def finish(self): print "connection lost",self.client_address # convert a list of headers to a dictionary for convenience def headsToDict(self,hdata): rzygi = {} for item in hdata: print '>',item item = item.split(':') if len(item) > 1: rzygi[item[0].strip()] = item[1].strip() return rzygi server = SocketServer.TCPServer(("",PORT),Handler) server.socket_type = socket.SOCK_STREAM # didnt help print "serving at port",PORT try: server.serve_forever() except KeyboardInterrupt: pass server.server_close()
如上所述,连接建立成功,但是立即丢弃,这使我认为代码是正确的,但是有一些东西丢失以保持套接字打开.这是服务器输出:
serving at port 8000 connection established ('127.0.0.1',52633) > GET / HTTP/1.1 > Upgrade: websocket > Connection: Upgrade > Host: localhost:8000 > Sec-WebSocket-Origin: http://localhost > Sec-WebSocket-Key: qWGnhdFQ6l8Xs9awgQURfA== > Sec-WebSocket-Version: 8 < HTTP/1.1 101 Web Socket Protocol Handshake < Upgrade: websocket < Connection: Upgrade < Sec-WebSocket-Accept: fei4E4LQvPnf4y2ilebVsxRofvc= connection lost ('127.0.0.1',52633)
如何保持套接字打开?
编辑:服务器代码注释
解决方法
每次处理后,连接都关闭.你应该留在那里读取传入的数据:
# incoming connection def setup(self): print "connection established",self.client_address def handle(self): while 1: try: self.data = self.request.recv(1024).strip() # incoming message self.headers = self.headsToDict(self.data.split("\r\n")) # its a handshake if "Upgrade" in self.headers and self.headers["Upgrade"] == "websocket": key = self.headers["Sec-WebSocket-Key"] accept = b64encode(sha1(key + MAGIC).hexdigest().decode('hex')) response = "HTTP/1.1 101 Switching Protocols\r\n" response += "Upgrade: websocket\r\n" response += "Connection: Upgrade\r\n" response += "Sec-WebSocket-Accept: "+accept+"\r\n\r\n" print response self.request.send(response) # its a normal message,echo it back else: print self.data self.request.send(self.data) except: print "except" break