Можно ли отправлять параллельные запросы из одного соединения Websocket? - PullRequest
0 голосов
/ 20 декабря 2018

Я на самом деле использую WebSockets 7 и все идет хорошо, несколько пользователей могут подключаться к веб-сокету, отправлять запросы и получать ответы от сервера, но есть проблема .

Если пользователь отправляет изображение, 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 голосов
/ 21 декабря 2018

Вместо ожидания 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 в более подходящее имя, например, handle или respond.

...