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

Máx*_*ekz 5 websocket python-3.x 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()
Run Code Online (Sandbox Code Playgroud)

更新

我正在使用循环,在尝试并行发出请求时,它不起作用。

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()
Run Code Online (Sandbox Code Playgroud)

当用户发送“长”,然后发送“短”时,“长”将使“短”等待直到被处理。:(

如果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
Run Code Online (Sandbox Code Playgroud)

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

use*_*342 1

read您可以在“后台”counter生成协程,而不是 waiting :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
Run Code Online (Sandbox Code Playgroud)

这样,花时间回复消息就不会延迟回复后续消息。

在一个不相关的注释中,我建议将read协程重命名为更适合其功能的名称,例如handlerespond