簡體   English   中英

如何在運行 while-True 循環時向任何連接的客戶端發送 websocket 更新?

[英]How to send websocket updates to any connected clients while running a while-True loop?

我有一個 Python3 程序,它運行“ while True ”循環直到停止,它偶爾會將數據保存到 MySQL 數據庫中。 我正在創建一個管理網站,與 Python 程序分開,我將能夠在其中觀察這些數據。

我現在希望能夠在對數據庫進行更改時在網站上收到通知。 我的想法是建立一個 websocket 連接,以便 Python 程序可以通過套接字向所有連接的客戶端發送消息,即所有打開的瀏覽器,如果數據庫表有任何更改。

我以前做過類似的事情,但在那種情況下,我必須等待 websocket 連接,然后才能開始“ while True ”循環。 在新場景中,我希望能夠同時擁有多個網站客戶端,並讓它們隨時連接,以及在不中斷 Python 程序循環的情況下斷開連接。

這是我之前代碼的簡化版本,我現在想更新它,以便能夠在有和沒有 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)

我似乎無法想出正確的搜索詞來找到解決方案,所以我在這里問。

我終於想通了。 這是我的解決方案,其中 websocket 服務器與其他邏輯在單獨的線程中運行,我可能正在更改一些內容以使其更整潔。 但這可以滿足我的一切需求。 隨意問任何問題。

請注意,在向所有連接的客戶端發送消息時,這會阻塞。 這就是我需要它工作的方式,但如果你希望它完全異步運行,你總是可以線程/子處理程序的邏輯/數據生成部分。

#!/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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM