Непрерывная отправка данных с сервера Python Flask клиенту через Websockets - PullRequest
0 голосов
/ 14 февраля 2020

Я настраиваю панель управления, для которой требуется Python Flask сервер для выборочной передачи транспортных данных c раз в несколько секунд и отправки этих данных на веб-страницу клиента через веб-сокеты. Я использую FlaskSocketIO для достижения этой цели.

Я могу отправить сообщение, например, по событию 'connect', но мне не удалось найти способ постоянно обновлять это сообщение. Это мой подход:

from flask import Flask, render_template, url_for, request
from flask_socketio import SocketIO, emit, send
import eventlet
eventlet.monkey_patch()

app = Flask(__name__)
socketio = SocketIO(app, logger=True, engineio_logger=True)

def listen():
    while True:
        message = # some updating message
        emit('message', message)
        socketio.sleep(1)

@app.route('/')
def index():
    return render_template('index.html')

@socketio.on('connect')
def handle_connect():
    listen()

if __name__ == "__main__":
    socketio.run(app, debug=True)

Регистратор говорит, что отправляет сообщение. Однако на стороне клиента сообщение не принимается. Клиентская сторона JavaScript:

var socket = io();

socket.on('message', function(msg) {
    console.log(msg);
});

Ответы [ 2 ]

0 голосов
/ 15 февраля 2020

Вы не можете добавить while True l oop в обработчик соединения, так как это предотвратит возврат обработчиком соединения и установление соединения.

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

0 голосов
/ 14 февраля 2020

У меня та же проблема с вами, в моем случае я хотел обновить приборную панель датчика, поэтому я изучаю шаблон наблюдателя, эта ссылка действительно хороша Шаблон наблюдателя . Внедрите SocketEmitObservator, используя наблюдателя, которого вы не нужно создавать слушателя (бесконечно, пока l oop) и сделать ваш код более чистым:

class SensorObserver(Observer):
    sensor_id: int
    sid = ''

    def __init__(self, sid,sensor_id=None):
        Observer.__init__(self)
        self.sensor_id = sensor_id
        self.sid = sid
        SensorPublisher().attach(self)

    def update(self, sensorData: DataModel) -> None:
        socket.emit("info",
                        {'sensor': subject},
                        namespace='/api/sector/machine',
                        room=self.sid)

    def __del__(self):
        SensorPublisher().detach(self)

class SensorPublisher(Subject, Singleton):
    _observers: List[SensorObserver] = []
    _sensorData: Dict[str, DataModel] = {}

    def attach(self, observer: SensorObserver) -> None:
        if observer not in self._observers:
            self._observers.append(observer)

    def notify(self, sensorModel: DataModel) -> None:
        for observer in self._observers:
            if sensorModel.sensor_id == observer.sensor_id:
                observer.update(sensorModel)

    def detach(self, observer: SensorObserver) -> None:
        if observer in self._observers:
            ob = self._observers.pop(self._observers.index(observer))
            del ob

    def update(self, sensorModel: DataModel):
        sendorId: str = str(sensorModel.sensor_id)
        self._sensorData[sendorId] = sensorModel
        self.notify(sensorModel)


#### And in the place where i update sensor data i put
SensorPublisher().update(dataStructList)

#### To create a observr just do
@socketio.on('connect')
def handle_connect():
    SensorObserver(self.sid, item)

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

...