Sudheej
Sudheej

Reputation: 2019

Emit events from flask_socketio server on set intervals

I have a React Client which needs to consume messages emitted by a flask_socketio server, it works fine if I emit a single message on 'connect' however if i keep emitting it in a while loop it doesn't get picked up on the client-side. I presume it could be due to action being performed in an active thread. I cannot find any posts online that talks about the issue.

Below is my React js client code.

class MyClient extends Component {

    constructor() {
        super();
        this.state = {
            endpoint:"http://127.0.0.1:5000",
            response: ""
        };
    }


    componentDidMount() {
        console.log("test")
        const {endpoint} = this.state;
        //Very simply connect to the socket
        const socket = socketIOClient(endpoint);
        //Listen for data
        socket.on("connect", dd => {

            socket.on("log", dx => this.setState({response: dx.data}));

          });

    }


    render() {

        const {response} = this.state;

        return (
            <div>
            <h1>Test {response}</h1>
            {console.log(response)}>
        </div>

        )
    }



}

The client looks for "log" to be emitted from the server, for now I added time to mock changing data. When client loads i see the data, and when I disconnect and reconnect the server I get to see the new data on the client. Am wondering how do I emit the data continuously

from flask import Flask, render_template, request, jsonify
from flask_socketio import SocketIO, emit
from flask_cors import CORS
from datetime import datetime
import time

now = datetime.now()

current_time = now.strftime("%H:%M:%S")


app = Flask(__name__)
app.config['SECRET_KEY'] = 'justasecretkeythatishouldputhere'

socketio = SocketIO(app,cors_allowed_origins="*")
CORS(app)


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


@app.route('/api')
def api():
    query = dict(request.args)
    socketio.emit('log', dict(data=str(query)), broadcast=True)
    return jsonify(dict(success=True, message='Received'))


@socketio.on('connect')
def on_connect():
    time.sleep(1)
    t = str(time.clock())
    print(t)
    socketio.emit('log', {'data': t, 'time': t})


if __name__ == '__main__':
    socketio.run(app,port=5000)

Below loop does not work, should i run it as a background thread or is there an async property that i need to add to socketio. Any help is greatly appreciated.

@socketio.on('connect')
def on_connect():
    while True:
        time.sleep(1)
        t = str(time.clock())
        print(t)
        socketio.emit('log', {'data': t, 'time': t})

Upvotes: 3

Views: 2435

Answers (1)

ngShravil.py
ngShravil.py

Reputation: 5048

In your client side you can make use of setInterval method to emit an event, after every few milliseconds.

On server side you can emit the event via which you can send the data.

So, all together, it will be something like below:

Client Side:

setInterval(function() {
    socket.emit('time');
}, 1) // 1 millisecond is almost close to continues

socket.on('time', function(data) {
    console.log(data)
});

Server Side:

@socket.on('time')
def time():
    now = datetime.now()
    current_time = now.strftime("%H:%M:%S")
    emit('time', current_time)

In the console log of your browser, you can see the continues data getting logged.

I hope this helps.

Note: Client side code, which I have provide here, is of pure JavaScript. Since, React is based on JavaScript, there will be some or the other way to use setInterval.

Upvotes: 4

Related Questions