Keeping the WebSocket connection alive

自作多情 提交于 2020-01-12 01:53:10

问题


I'm doing a study on WebSocket protocol and trying to implement a simple ECHO service for now with Python on the backend. 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


回答1:


The connection is closed each time after 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


来源:https://stackoverflow.com/questions/8218936/keeping-the-websocket-connection-alive

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!