Как отправлять обновления веб-сокетов любым подключенным клиентам во время работы while-True l oop? - PullRequest
0 голосов
/ 16 июня 2020

У меня есть программа Python3, которая запускает « while True » - l oop до остановки, которая иногда сохраняет данные в базе данных MySQL. Я создаю административный веб-сайт, отдельный от программы Python, на котором я смогу наблюдать за этими данными.

Теперь я хочу иметь возможность получать уведомления на веб-сайте, когда были внесены изменения в базу данных. Моя мысль заключалась в том, чтобы настроить соединение с веб-сокетом, чтобы программа Python могла отправлять сообщение через сокет всем подключенным клиентам, то есть всем открытым браузерам, если в таблице базы данных были какие-либо изменения.

Я делал нечто подобное раньше, но в этом случае мне пришлось ждать подключения к веб-сокету до того, как запустится « while True » - l oop. В новом сценарии я хочу иметь возможность иметь несколько клиентов веб-сайта одновременно и позволить им подключаться в любое время, а также отключаться, не прерывая программы Python l oop.

Это упрощенная версия моего предыдущего кода, который я теперь хочу обновить, чтобы иметь возможность запускать как с клиентами websocket, так и без них.

import asyncio
import websockets

socket_server = websockets.serve(run, "127.0.0.1", 5055)
asyncio.get_event_loop().run_until_complete(socket_server)
console_log("Waiting for socket connection...")
asyncio.get_event_loop().run_forever()

async def run(ws):
    while True:
        db_has_updated = do_stuff()
        if db_has_updated:
            await ws.send(data)

Кажется, я просто не могу найти правильный поиск условия, чтобы найти решение, поэтому я спрашиваю здесь.

1 Ответ

0 голосов
/ 21 июня 2020

Разобрался наконец! Вот мое решение с сервером websocket, работающим в отдельном потоке от другого logi c. Я, наверное, кое-что меняю, чтобы сделать его аккуратнее, но здесь есть все, что мне нужно. Не стесняйтесь задавать любые вопросы.

Имейте в виду, что это блокирует отправку сообщений всем подключенным клиентам. Именно так мне и нужно было работать, но вы всегда можете потратить / обработать часть логики / генерации данных программы, если хотите, чтобы она выполнялась полностью асинхронно.

#!/usr/bin/env python3

import asyncio
import websockets
import threading
import time
import random

def gen_data():
    print("Generating data...")
    time.sleep(3)
    data = random.randint(1, 10)
    
    return data

async def send(client, data):
    await client.send(data)

async def handler(client, path):
    # Register.
    print("Websocket Client Connected.", client)
    clients.append(client)
    while True:
        try:
            print("ping", client)
            pong_waiter = await client.ping()
            await pong_waiter
            print("pong", client)
            time.sleep(3)
        except Exception as e:
            clients.remove(client)
            print("Websocket Client Disconnected", client)
            break

clients = []
start_server = websockets.serve(handler, "localhost", 5555)

asyncio.get_event_loop().run_until_complete(start_server)
threading.Thread(target = asyncio.get_event_loop().run_forever).start()

print("Socket Server Running. Starting main loop.")

while True:
    data = str(gen_data())
    message_clients = clients.copy()
    for client in message_clients:
        print("Sending", data, "to", client)
        try:
            asyncio.run(send(client, data))
        except:
            # Clients might have disconnected during the messaging process,
            # just ignore that, they will have been removed already.
            pass
...