是否可以使用 Javascript 连接到 Python 套接字服务器?

Is it possible to connect to a Python socket server with Javascript?

我正在使用模块 socketserver:

创建 Python socketserver
import socketserver

class MyTCPHandler(socketserver.BaseRequestHandler):
    def setup(self):
        pass
    def handle(self):
        pass
with socketserver.TCPServer(("localhost", 4000), MyTCPHandler) as server:
    server.serve_forever()

我使用了 Python 模块 websockets,我可以使用 WebSocket API 访问 Javascript 中的 websocket。在没有完全理解 Python 模块 socketserver 真正做什么的情况下,我尝试使用 websocket 连接到 TCP socketserver

var socket = new WebSocket('ws://localhost:4000'); // ERROR: Firefox can’t establish a connection to the server at ws://localhost:4000/.

每次,Firefox 都会抛出错误 Firefox can’t establish a connection to the server at ws://localhost:4000/. 然后,我尝试使用 Python http 模块连接到服务器:

import http.client
httpConnection = http.client.HTTPSConnection("localhost:4000", timeout=10)
print(httpConnection) # HTTP Connection Object

遗憾的是,这奏效了。现在,我了解到 Python 的内置 socketserver 模块创建只能通过 HTTP 访问。现在,我想知道是否可以在浏览器中使用 Javascript 连接到 Python TCP socketserver。如果没有,我将只使用 websockets 或弄清楚如何创建我自己的 websocket。

使用 socketserver,您必须在代码中实施 websocket 协议。网上有几个教程,例如here.

虽然来自@scenox 的博客 link 非常有帮助,但它已经过时了。我做了更多搜索并修复它以更好地反映当今的 websocket 标准:

def setup(self):
    print(type(self))
    data = str(self.request.recv(1024))
    if "Upgrade: websocket" in data: # Connection: Upgrade might be Connection: keep-alive, Upgrade
        key = base64.b64encode(hashlib.sha1((data.split("Sec-WebSocket-Key: ")[1].split("\r\n")[0] + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").encode('ascii')).digest()).decode('ascii') # Encode as ascii and then decode it
        self.request.sendall(f"HTTP/1.1 101 Switching Protocols\r\nSec-WebSocket-Accept: {key}\r\nConnection: Upgrade\r\nUpgrade: websocket\r\n\r\n".encode()) # Encode it so that it gets sent as a bytes-like object
        while True:
            # I haven't figured out how to decode frames yet.
    else:
        self.request.sendall("HTTP/1.1 400 Bad Request\r\n" + \
                             "Content-Type: text/plain\r\n" + \
                             "Connection: close\r\n" + \
                             "\r\n" + \
                             "Incorrect request")

我还没有解码帧,但我至少建立了连接。