简体   繁体   English

如何通过使用python flask socket.io和线程异步从Redis获取实时数据?

[英]How to asynchrony get a real time data from redis by using python flask socket.io and threads?

My program collects data from sensors and sends this data to web interface, which shows it in real time graphs and sends some commands back. 我的程序从传感器收集数据,并将该数据发送到Web界面,该界面以实时图形的形式显示并向后发送一些命令。

The problem is that data sending has a big delay or sends old data. 问题是数据发送有很大的延迟或发送了旧数据。 What i should change to send data async to both ways? 我应该更改以两种方式异步发送数据吗?

I simplified my code. 我简化了代码。 Example 1, when data comes one time in a few minutes: 示例1,当数据在几分钟内到达一次时:

# System stuff
import os
import sys
import serial
# Multiprocessing
from multiprocessing import Process
from threading import Thread # for same memory
import timeit
from time import sleep
# database
import redis
# Web server
from flask import Flask, render_template
from flask_socketio import SocketIO, emit, send, join_room, leave_room, close_room, rooms, disconnect

# Config
DEBUG = True


db = redis.StrictRedis(host='localhost', port=6379, db=0)
#db vars
db.set('velocity', 0.0)
db.set('distance', 0.0)


def webServer(db):
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'secret!'
    socketio = SocketIO(app)


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


    def exchangeData():
        prev_distance = 0.00
        while(True):
            distance = round(float(db.get('distance')), 2)
            if(distance != prev_distance):
                velocity = round(float(db.get('velocity')), 2)
                distance = round(float(db.get('distance')), 2)              
                socketio.emit('exchangeData', {
                    'velocity': velocity,
                    'distance': distance,
                })              
                prev_distance = distance                
                print("DATA sended: %s m/s" % velocity) 

            sleep(0.2)      

    @socketio.on('connect')
    def test_connect():
        t_exchangeData = Thread(target=exchangeData).start()    

    socketio.run(app, debug=True, host="0.0.0.0")


def newData(db):
    c = 0.00
    while(True):
        db.set('velocity', c)
        db.set('distance', c)
        c += 1.00
        sleep(1)




if __name__ == '__main__':
    p_newData = Process(target=newData, args=(db,)).start()
    p_webServer = Process(target=webServer, args=(db,)).start()
    #p_checkConnection = Process(target=checkConnection, args=(db, HOSTNAME, pinglog)).start()
    #p_calcVD = Process(target=calcVD, args=(db,)).start()

In browser, I get this with latency about 2 minutes: 在浏览器中,我的等待时间约为2分钟:

Object {velocity: 218, distance: 218}
// two minutes later
Object {velocity: 306, distance: 306}
// two minutes later
Object {velocity: 306, distance: 306}

Example 2, when I do not use if statement and sleep: 示例2,当我不使用if语句和sleep时:

# System stuff
import os
import sys
import serial
# Multiprocessing
from multiprocessing import Process
from threading import Thread # for same memory
import timeit
from time import sleep
# database
import redis
# Web server
from flask import Flask, render_template
from flask_socketio import SocketIO, emit, send, join_room, leave_room, close_room, rooms, disconnect

# Config
DEBUG = True


db = redis.StrictRedis(host='localhost', port=6379, db=0)
#db vars
db.set('velocity', 0.0)
db.set('distance', 0.0)


def webServer(db):
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'secret!'
    socketio = SocketIO(app)


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


    def exchangeData():
        prev_distance = 0.00
        while(True):
            #distance = round(float(db.get('distance')), 2)
            #if(distance != prev_distance):
            velocity = round(float(db.get('velocity')), 2)
            distance = round(float(db.get('distance')), 2)              
            socketio.emit('exchangeData', {
                'velocity': velocity,
                'distance': distance,
            })              
            prev_distance = distance                
            print("DATA sended: %s m/s" % velocity) 

            #sleep(0.2)      

    @socketio.on('connect')
    def test_connect():
        t_exchangeData = Thread(target=exchangeData).start()    

    socketio.run(app, debug=True, host="0.0.0.0")


def newData(db):
    c = 0.00
    while(True):
        db.set('velocity', c)
        db.set('distance', c)
        c += 1.00
        sleep(1)




if __name__ == '__main__':
    p_newData = Process(target=newData, args=(db,)).start()
    p_webServer = Process(target=webServer, args=(db,)).start()
    #p_checkConnection = Process(target=checkConnection, args=(db, HOSTNAME, pinglog)).start()
    #p_calcVD = Process(target=calcVD, args=(db,)).start()

In this case, i get data in real time, but it is the same data, and changes only one time in few minutes: 在这种情况下,我实时获取数据,但它是相同的数据,并且在几分钟内仅更改一次:

Object {distance: 3, velocity: 3}
Object {distance: 3, velocity: 3}
Object {distance: 3, velocity: 3}
// repeating around 2 minutes
Object {distance: 357, velocity: 357} 
// repeating again...

The main problem was that I did not add these two lines: 主要问题是我没有添加这两行:

import eventlet
eventlet.monkey_patch()

Also, while I tried to find solution, made a mistake when I called data from redis out of while loop. 另外,当我尝试寻找解决方案时,当我从while循环外的redis调用数据时犯了一个错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM