Я пытаюсь создать сервер веб-сокетов в python, где клиент отправляет сообщение на сервер, сообщая ему, на какие данные он хочет подписаться, и когда происходит обновление этих данных, сервер отправляет обновленные данные. Я готов сделать это по-разному, если есть лучший способ сделать это.
Как я вижу это работает:
- WS-сервер прослушивает для подписки
- при получении подписки сохраняет соединение в переменной, связанной с этой подпиской
- Другой процесс будет проверять эту переменную на наличие соединений и отправлять данные.
Вот то, что я придумал, но я продолжаю получать и функция не ожидала ошибки на ws_random
/usr/lib/python3.7/threading.py:865: RuntimeWarning: coroutine 'ws_random' was never awaited
self._target(*self._args, **self._kwargs)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Код:
import asyncio
import sys
from threading import Thread
import random
import websockets
ws_connections = set()
ws_valid_subs = [
'random'
]
ws_subs = {}
async def ws_handler(websocket, path):
global ws_connections, ws_valid_subs, ws_subs
try:
async for message in websocket:
print(message)
# check if subscription endpoint is valid
if message in ws_valid_subs:
# check if the endpoint key exists and create it
if message not in ws_subs.keys():
ws_subs.update({message: set()})
# add subscription
ws_subs[message].add(websocket)
except:
print("Unexpected error:", sys.exc_info()[0])
raise
async def ws_random():
global ws_connections, ws_valid_subs, ws_subs
while True:
if 'random' in ws_subs.keys():
for websocket in ws_subs['random']:
await websocket.send(random.randrange(1000))
await asyncio.sleep(1)
def main():
Thread(target=ws_random).start()
start_server = websockets.serve(ws_handler, "0.0.0.0", 8765)
loop = asyncio.get_event_loop()
loop.run_until_complete(start_server)
loop.run_forever()
if __name__ == '__main__':
sys.exit(main())