Python Websockets无法通过互联网连接

5

我只是想建立一个基本的互联网websocket连接。代码似乎没问题——因为当连接到本地主机时它能够工作,但是当我尝试在互联网上使用它时却失败了。我正在使用websockets库,我的服务器看起来像这样:

#!/usr/bin/env python3

import asyncio
import websockets
from logging import getLogger, INFO, StreamHandler

logger = getLogger('websockets')
logger.setLevel(INFO)
logger.addHandler(StreamHandler())

clients = set()

async def handler(websocket, path):
    global clients
    clients.add(websocket)
    try:
        await asyncio.wait([ws.send("Hello!") for ws in clients])
        await asyncio.sleep(10)
    finally:
        clients.remove(websocket)

start_server = websockets.serve(handler, host='127.0.0.1', port=6969)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

客户端的外观如下:

<!DOCTYPE html>
<html lang="en"><head>
    <meta charset="UTF-8">
    <title>Chat</title>
</head>

<body style="margin:0">
    <script type="text/javascript">
        var ws = new WebSocket("ws://127.0.0.1:6969/");
        var messages = document.getElementById('messages');
        ws.onmessage = function (event) {
            var messages = document.getElementById('messages');
            var message = document.createElement('li');
            var content = document.createTextNode(event.data);
            message.appendChild(content);
            messages.appendChild(message);
        };
    </script>
    Messages:
    <ul id="messages"><li>Hello!</li></ul>


</body></html>

所遇问题为,客户端表现正常,但在我在Ubuntu服务器上运行该服务(并确保将端口6969转发到该机器),并尝试通过互联网连接时出现问题。主机名解析正常,因为我可以使用ssh连接来启动服务器,但是尝试连接WebSocket始终显示以下错误消息: Firefox 无法建立与 ws://<远程服务器URL>:6969/ 的连接。 其他浏览器类似。此外,如果有人想知道,记录器没有输出任何有用的信息(由于连接失败,因此服务器没有执行任何操作)。

在服务器上,我不改变任何代码,唯一的区别是当它在远程服务器上运行时,我会将客户端中的这一行 var ws = new Websocket("ws://127.0.0.1:6969/"); 更改为 var ws = new Websocket("ws://<远程服务器URL>:6969/"); - ocket8888
telnet命令正确解析IP地址并尝试连接,但随后显示“连接被拒绝”。另外,如果您能编辑评论以删除网址,我会非常感激;我还没准备好接受所有人的渗透测试:P(我也会从问题中将其删除 - 真是糊涂) - ocket8888
将您的websockets.serve()代码行更改为:websockets.serve(handler, port=6969)。这样在任何环境下都应该能够正常工作。 - Robᵩ
@Robᵩ 我将其更改为 websockets.serve(handler, host="", port=6969),现在我可以连接了。如果您想写一个答案,我很乐意接受,并且我也会感激一下为什么我所做的不起作用的解释。 - ocket8888
1个回答

13

您的句子:

websockets.serve(handler, host='127.0.0.1', port=6969)

提供了一个特定的地址,用于Websockets服务器的监听。您的服务器将在该地址上进行监听;任何发送到其他地址的请求都不会被看到。

来自https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_server

host参数可以是一个字符串,在这种情况下,TCP服务器将绑定到hostport。主机参数也可以是字符串序列,在这种情况下,TCP服务器将绑定到序列的所有主机上。如果host是空字符串或None,则假定所有接口并返回多个套接字的列表(最有可能是IPv4和另一个IPv6)。

您已将Web服务器绑定到127.0.0.1,这是一种特殊的地址,只指向本地计算机。此地址也称为localhost。没有其他计算机可以连接到您的localhost

解决方案是提供一个空字符串或None(默认值)。在这种情况下,您的Web服务器将侦听发送到任何地址的请求。

websockets.serve(handler, port=6969)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接