简体   繁体   English

保持WebSocket连接活动

[英]Keeping the WebSocket connection alive

I'm doing a study on WebSocket protocol and trying to implement a simple ECHO service for now with Python on the backend. 我正在研究WebSocket协议,并尝试在后端使用Python实现一个简单的ECHO服务。 It seems to work fine but the connection drops right after being established. 它似乎工作正常但连接在建立后立即下降。

Here is my client: 这是我的客户:

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

Here is the server: 这是服务器:

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()

As mentioned, the connection is established successfully but then drops straight away, which makes me think the code is correct but there is something missing to keep the socket open. 如上所述,连接已成功建立,但随后立即掉线,这让我觉得代码是正确的,但是缺少一些东西来保持套接字打开。 Here is the server output: 这是服务器输出:

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)

How do I keep the socket open? 如何打开插座?


edit: server code comments 编辑:服务器代码注释

The connection is closed each time after handle . 每次handle后连接都会关闭。 You should rather stay there reading incoming data: 你应该留在那里阅读传入的数据:

# 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM