Как асинхронно передать состояние из серверной части во внешний интерфейсPython

Программы на Python
Anonymous
 Как асинхронно передать состояние из серверной части во внешний интерфейс

Сообщение Anonymous »

Я пытаюсь создать простое приложение с помощью Reflex.
Мой вариант использования отличается от большинства примеров, показанных в документации.
Мне нужно постоянно получать данные из сокета UDP, анализировать содержимое, а затем передавать определенные значения из серверной части во внешний интерфейс.
Мой приемник и анализатор работают нормально, однако я не могу отправлять обновления из серверной части во внешний интерфейс.

Код: Выделить всё

import threading
from typing import Callable
import reflex as rx
from rxconfig import config
import socket

from .forza_dash import ForzaDash

class UDPReceiver:
type Callback = Callable[[bytes], None]
sock: socket = None
subscriber: Callback = None
running: bool = False

def __init__(self, port: int):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
addr = ('0.0.0.0', port)
self.sock.bind(addr)

def receive_loop(self):
while self.running:
message, _ = self.sock.recvfrom(1024)
if self.subscriber != None:
self.subscriber(message)

def start(self):
if self.running:
return
self.running = True
threading.Thread(target=self.receive_loop).start()

def stop(self):
self.running = False

def subscribe(self, callback: Callback):
self.subscriber = callback

class State(rx.State):
# UDP receiver backend only
_udp_receiver: UDPReceiver = None
# last update backend only
_last_update: ForzaDash = None

# timestamp
tstamp: int = -1

def __init__(self, *args, **kwargs):
print("State __init__")
super().__init__(*args, **kwargs)
self._udp_receiver = UDPReceiver(5300)
self._udp_receiver.subscribe(self.on_data)

def start_receiver(self):
self._udp_receiver.start()

def on_data(self, data: bytes):
print(f"State got {len(data)} bytes")
if len(data) == ForzaDash.size():
# parse and map desired values
update = ForzaDash(data)
self._last_update = update
self.tstamp = update.tod

@rx.var
def timestamp(self) -> int:
return self.tstamp
#return self._last_update.tod

@rx.page(on_load=State.start_receiver)
def index() -> rx.Component:
return rx.container(
rx.vstack(
rx.text(
f"time: {State.tstamp}"
),
),
)

app = rx.App()
app.add_page(index)
Когда я запускаю приложение, мой поток-получатель запускается, получает данные, байты анализируются и значения верны. Однако временная метка @rx.var вообще не обновляется. Его внутреннее значение остается -1.
Есть ли способ принудительно или инициировать обновление состояний от серверной части к внешней?

Подробнее здесь: https://stackoverflow.com/questions/798 ... o-frontend

Вернуться в «Python»