Я занимаюсь разработкой приложения с компонентом p2p. Мне нужно добавить функцию, в которой Алиса, Боб и Джон должны обмениваться данными и сообщать друг другу, на каком этапе процесса они находятся. Это может выглядеть так:
- Алиса отправляет данные Бобу и Джону (через сервер).
- Боб и Джон оба действуют на основе данных и уведомляют других 2 пользователей, что они готовы для следующего шага.
- После того, как каждый пользователь завершил каждый шаг, все они должны снова обмениваться данными для следующего шага.
Я использую AIOHTTP для своего сервера веб-сокетов. Я также использую MySQL (AIO MYSQL) и Redis (AIOREDIS). Каждый пользователь подключается к серверу через веб-сокеты. Я знаю, что я мог бы просто заставить их постоянно пинговать сервер через WS для запроса MySQL, обмениваясь данными между пользователями, но это кажется неправильным.
Что было бы лучше, если бы они отправляли данные на сервер только тогда, когда у них есть новые данные для отправки. Таким образом, все пользователи не постоянно привязывают API. Для достижения sh этого я думаю использовать каналы Redis следующим образом:
async def handler(request):
ws = web.WebSocketResponse()
await ws.prepare(request)
task = request.app.loop.create_task(
read_subscription(ws,
request.app['redis']))
try:
async for msg in ws:
# handle incoming messages
# use ws.send_str() to send data back
...
finally:
task.cancel()
async def read_subscription(ws, redis):
channel, = await redis.subscribe('channel:1')
try:
async for msg in channel.iter():
answer = process message(msg)
ws.send_str(answer)
finally:
await redis.unsubscribe('channel:1')
Вопрос: Как это можно сделать с помощью Redis? Я рассматриваю следующие варианты:
- Каждый пользователь имеет свой собственный канал Redis, на который могут подписаться другие пользователи.
- 1 выделенный канал Redis, но сервер веб-сокетов будет фильтровать то, что отображается каждому пользователю (только то, какие сообщения они должны видеть своими запросами на подключение к другим пользователям).
- Каждое соединение (скажем, между Алексом, Бобом и Джоном) получает собственный канал Redis, если необходимо.
Я более решительно рассматриваю 1 и 3. 3 кажется лучшим способом, но я не уверен. Я никогда не делал это раньше. Какой путь правильный? Я пытаюсь избежать неконтролируемого использования ресурсов и ненужных сложностей.