【问题标题】:Is it possible to connect to a Python socket server with Javascript?是否可以使用 Javascript 连接到 Python 套接字服务器?
【发布时间】:2021-08-05 01:56:33
【问题描述】:

我正在使用模块 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。

【问题讨论】:

    标签: javascript python http browser websocket


    【解决方案1】:

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

    【讨论】:

    • 那么,从本质上讲,websocket 只是一个带有额外标头的 HTTP 连接?而服务器只需要做一些额外的处理?
    • 这不是 HTTP 连接,但类似。与 HTTP 不同,WebSocket 提供全双工通信。 WebSocket 在端口 80 或 443 上启用 TCP 顶部的消息流。WebSocket 握手使用 HTTP 升级标头从 HTTP 协议更改为 WebSocket 协议。所以是的,服务器需要对 websocket 做额外的处理。您可以阅读有关 websocket 协议的更多信息,例如在维基百科上。
    【解决方案2】:

    虽然来自@scenox 的博客链接非常有用,但它已经过时了。我进行了更多搜索并对其进行了修复,以更好地反映当今的 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")
    

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

    【讨论】:

      猜你喜欢
      • 2011-03-21
      • 1970-01-01
      • 1970-01-01
      • 2021-02-11
      • 1970-01-01
      • 2023-02-08
      • 2011-04-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多