Python-SocketIO服务器花费很长时间触发事件

问题描述 投票:1回答:1

我有一个python websocket服务器,试图与javascript websocket客户端(嵌入HTML)进行通信。事件将立即从服务器emit生成,但是尽管客户端和服务器都在本地托管,服务器仍需要30秒钟以上的时间来发送事件触发器。

这是服务器的相关代码:

sio = socketio.AsyncServer(cors_allowed_origins='*')
app = web.Application() #aiohttp web server
loop = asyncio.get_event_loop()
sio.attach(app)

async def index(request):
    with open('./index.html') as f:
        return web.Response(text=f.read(), content_type='text/html')

app.router.add_get('/', index)
app.router.add_get('/index.html', index)

if __name__ == '__main__':
    web.run_app(app)

事件被这样触发(编辑,这必须通过事件循环来完成,因为emit是从同步函数运行的异步函数。):

print('Starting event')
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(sio.emit('ChangeProgressState'))
loop.close()
print('Event has been fired.')

但是,打印语句会立即显示。在客户端,我正在连接并尝试消耗此类事件:

const socket = io.connect("http://localhost:8080", {
      transports: ['websocket']
})

socket.on("ChangeProgressState", function (data) {
    console.log("got event.")
    //some code here...
});

但是,从事件触发到花费时间以及javascript套接字注意到的时间可能是很长的时间,从30秒到有时是几分钟。我在这里做错什么了吗?

应该注意,几乎没有(2%-5%)的资源(包括内存和CPU)被消耗,因此我目前不认为这是问题所在。任何帮助将非常感激。

编辑11/15/2019:我尝试查看该应用程序的网络选项卡(树莓派上的铬浏览器)。它似乎显示了最初的套接字连接,但是就套接字之间的通信而言,即使事件最终触发之后,它也没有显示任何内容。

编辑2:这绝对是服务器端的问题。我可以立即将事件从JS客户端发送到python服务器,但另一个方向是需要很长时间才能到达。我不太清楚为什么。

javascript python websocket socket.io aiohttp
1个回答
0
投票

啊,好吧,我的直觉说这听起来像是客户在长时间轮询。许多套接字库首先建立长轮询,然后再升级到ws连接。

看了Socket.io

...首先建立长轮询连接,然后尝试升级到在侧面经过“测试”的更好的传输,例如WebSocket。 ...

所以我不认为您做错了什么,这只是建立WebSocket连接的初始化过程。

至于python部分,老实说,这对我来说有点模糊。我的第一个猜测是,循环代码不会阻止打印语句的执行-但是我比JavaScript更熟悉JavaScript,因此在这方面还不确定。我的第二个猜测是,我确实从其他发布/订阅库中知道服务器端引擎有时会利用某种中间层(有时是缓存,有时是队列)来帮助确保消息的发送/接收,这也是一种可能。

额外花絮:我怀疑如果您查看浏览器开发工具的网络标签,它将显示该行为,某种形式的HTTP请求,然后最终您将看到套接字连接。玩弄关闭/打开Python服务器/服务的操作,还将展示socket.io在浏览器和其他情况下的健壮性,以了解它在处理各种互联网通信协议时如何处理不稳定的网络。

© www.soinside.com 2019 - 2024. All rights reserved.