【问题标题】:Python Asyncio Websocket not detecting a disconnect on wifi but does on localhostPython Asyncio Websocket 未检测到 wifi 上的断开连接,但在 localhost 上检测到
【发布时间】:2018-04-28 09:44:56
【问题描述】:
async def relayHandler(request):
print('Websocket connection starting')
ws = aiohttp.web.WebSocketResponse(autoclose=True)
await ws.prepare(request)
print('Websocket connection ready')

async for msg in ws:
    print(msg)
    if msg.type == aiohttp.WSMsgType.TEXT:
        print(msg.data)
        if msg.data == 'close':
            await ws.close()
        else:
            await ws.send_str(msg.data + '/answer')
    elif msg.type == aiohttp.WSMsgType.ERROR:
        print('ws connection closed with exception %s' %ws.exception())
print('Websocket connection closed')
return ws

这是我的 websocket 处理程序,它在 asyncio 之上使用 aiohttp。问题是如果我断开客户端 wifi 连接,它不会检测到连接丢失。我也尝试使用 Websockets 模块,但同样的事情发生了。但是当客户端在本地主机上时,它工作得很好。 造成这种情况的主要原因是什么,如果有人可以解释如何在 asyncio 中正确捕获网络异常。

【问题讨论】:

    标签: python-3.x websocket python-asyncio


    【解决方案1】:

    TLDR;通过客户端 ping 您的服务器。

    这就是 TCP 堆栈的工作原理:优雅断开连接需要向对等方发送数据包。如果网络中断,则无法进行数据传输。

    本地主机网络有关于断开连接的所有知识,但真实网络会丢失有关所有移动部件的信息。

    检测断开连接的唯一可靠方法是等待来自对端的消息(可以是 ping 消息或常规数据包)并超时。

    如果超时--对等体消失了,通信通道的本地端也应该关闭。

    这就是为什么通过 TCP 进行的任何长期通信都比看起来要复杂一些——所有生产级系统都在内部使用 ping 和超时。它不仅影响 websocket,还影响任何具有自定义协议的信使。

    【讨论】:

    • Thnks Andrew,我知道我们必须 ping 系统,但是你能解释一下在本地主机上这有什么不同吗,更重要的是为什么在连接结束时没有抛出异常,在内部某处 asyncio或 web-sockets 正在检查流是否有数据,如果流不存在,它应该抛出异常。
    • @NivedPv 那是因为 TCP 建立在无连接、无状态的 IP 协议之上——在底层它只是抛出自包含的 IP 数据包。因此,如果您正在等待来自对等方的数据,TCP 无法区分已破坏的连接和尚未向您发送任何数据的对等方的健康连接。所以检查连接健康的唯一方法 - 发送任何东西并检查反应
    • @AndriyMaletsky 就是这样,非常感谢您,所以如果您收听消息,我们不能说连接是否断开。非常感谢,我可以在 websocket 中使用 ping 来解决这个问题,以检查客户端是否在线,或者我必须创建一个自定义消息,客户端必须回复确认。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-31
    相关资源
    最近更新 更多