通过 Websockets 从 Python Flask 服务器连续向客户端发送数据

Posted

技术标签:

【中文标题】通过 Websockets 从 Python Flask 服务器连续向客户端发送数据【英文标题】:Continuously sending data from Python Flask server to client through Websockets 【发布时间】:2020-02-14 09:02:26 【问题描述】:

我正在设置一个仪表板,它需要 Python Flask 服务器每隔几秒左右获取一次公共交通数据,并通过 websockets 将此数据发送到客户端网页。我正在使用 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);
);

【问题讨论】:

【参考方案1】:

我和你有同样的问题,在我的情况下,我想更新传感器仪表板,所以我研究了观察者模式,这个链接真的很好Observer Pattern。实现一个 SocketEmitObservator,使用你不需要创建一个观察者监听器(无限循环)并使您的代码更干净:

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)

在我的情况下,我是这样使用的,但你可以适应你的问题

【讨论】:

【参考方案2】:

您不能在连接处理程序中添加while True 循环,因为这会阻止连接处理程序返回并建立连接。

您可以将其作为对建立连接后客户端发送的另一个事件的响应,也可以启动实现此循环的后台任务。连接处理程序需要快速返回以允许连接发生。

【讨论】:

以上是关于通过 Websockets 从 Python Flask 服务器连续向客户端发送数据的主要内容,如果未能解决你的问题,请参考以下文章

通过 Websockets 在 Nodejs 和 Python 之间进行通信

将 JavaScript 通过 websockets 发送的最后一个字符剥离到 Python

使用 Python 通过 WebSockets 访问 API

Websockets - 尝试将 Python 代码转换为节点

Azure 认知服务 - 使用 python 和 websockets 自定义语音

Python 和 websockets - 发送音频流