是否可以从一个Websocket连接发送并行请求?

时间:2018-12-20 19:25:30

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

我实际上正在使用WebSockets 7,并且一切正常,多个用户可以连接到websocket,发送请求和接收来自服务器的响应,但是存在一个问题

如果用户发送图像,pdf,歌曲,视频等。服务器必须解决该问题,将其保存到数据库,进行转换等并发送响应,则用户可以将更多数据发送到websocket,但该数据将排队等待,直到当用户迫切希望在最短的时间内发送数据时,先前的消息会得到响应,这是不好的。

连接的用户是否有可能发送并行请求

这是我正在使用的示例

import asyncio
import websockets

# Process the data
async def read(msg, websocket):
    # In this case, the message will get back to the user
    await websocket.send(msg)

async def counter(websocket, path):
    try:
        async for message in websocket:
            await read(message, websocket)
    except websockets.exceptions.ConnectionClosed:
        pass

try:
    asyncio.get_event_loop().run_until_complete(
        websockets.serve(counter, '0.0.0.0', 4444, max_size=10**8))
    asyncio.get_event_loop().run_forever()
except KeyboardInterrupt:
    quit()

更新

我正在使用循环,在尝试并行发出请求时,它仍然无法工作。

import asyncio
import websockets

# Process the data
async def read(msg, websocket):
    # In this case, the message will get back to the user
    if msg == 'long':
        # Some blocking operations
        pass
    elif msg == 'short':
        # Some blocking operations
        pass
    # elif msg == 'some other conditions that could take more or less time':
        # Some blocking operations
        # pass
    # elif msg == 'some other conditions that could take more or less time':
        # Some blocking operations
        # pass
    # elif msg == 'some other conditions that could take more or less time':
        # Some blocking operations
        # pass
    # elif msg == 'some other conditions that could take more or less time':
        # Some blocking operations
       # pass

    print("Did a {0} task".format(msg))
    await websocket.send(msg)

async def counter(websocket, path):
    loop = asyncio.get_event_loop()
    try:
        async for message in websocket:
            loop.create_task(read(message, websocket))
    except websockets.exceptions.ConnectionClosed:
        pass

try:
    asyncio.get_event_loop().run_until_complete(
        websockets.serve(counter, '0.0.0.0', 4444, max_size=10**8))
    asyncio.get_event_loop().run_forever()
except KeyboardInterrupt:
    quit()

当用户发送“ long”然后发送“ short”时,“ long”将使“ short”等待处理。 :(

如果在每个条件中添加await asyncio.sleep(),将并行进行,但是最长的任务必须具有最长的时间asyncio.sleep() 例如:

    if msg == 'this is probably the longest task to do':
        await asyncio.sleep(5);
        # Some blocking operations
    elif msg == 'this is probably the shortest task to do':
        await asyncio.sleep(1);
        # Some blocking operations
    elif msg == 'some other conditions that could take more or less time':
        await asyncio.sleep(4);
        # Some blocking operations
    elif msg == 'some other conditions that could take more or less time':
        await asyncio.sleep(2);
        # Some blocking operations
    elif msg == 'some other conditions that could take more or less time':
        await asyncio.sleep(3);
        # Some blocking operations
    elif msg == 'some other conditions that could take more or less time':
        await asyncio.sleep(1);
        # Some blocking operations

如果我删除await asyncio.sleep(),代码将无法并行运行

1 个答案:

答案 0 :(得分:1)

您可以让read在“背景”中生成counter协程,而不是等待read

async def counter(websocket, path):
    loop = asyncio.get_event_loop()
    try:
        async for message in websocket:
            loop.create_task(read(message, websocket))
    except websockets.exceptions.ConnectionClosed:
        pass

这样,花时间响应消息不会延迟响应后续消息。

在不相关的注释上,我建议将read协程命名为更适合其用途的名称,例如handlerespond