简体   繁体   中英

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.

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:

# 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:

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:

# 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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