javascript 保持 WebSocket 连接处于活动状态

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8218936/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 02:41:04  来源:igfitidea点击:

Keeping the WebSocket connection alive

javascriptpythonsocketshttp-headerswebsocket

提问by Dreen

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.

我正在研究 WebSocket 协议,并尝试在后端使用 Python 实现一个简单的 ECHO 服务。它似乎工作正常,但连接建立后立即断开。

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

编辑:服务器代码注释

采纳答案by pimvdb

The connection is closed each time after handle. You should rather stay there reading incoming data:

每次在 之后关闭连接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