保持WebSocket连接活跃
我正在研究WebSocket协议,想用Python在后台实现一个简单的回声服务。现在看起来运行得不错,但连接在建立后马上就断开了。
这是我的客户端代码:
<!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)
我该如何保持连接不掉线呢?
编辑:服务器代码的注释
1 个回答
7
每次在执行完handle
后,连接都会关闭。你应该保持连接,继续读取进来的数据:
# 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