0

I made a countdown timer and i placed emit function in the for loop. But emit doesn't send my timer data to client.

This is my python server-side code:

from flask import Flask,render_template,render_template_string
from flask_socketio import SocketIO, emit

app = Flask(__name__) 
app.config['SECRET KEY'] = 'random'
socketio = SocketIO(app)

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

@socketio.on('test_timer')
def Timer(seconds=3600):
    def hms(seconds): # hour minute second function
        h = seconds // 3600
        m = seconds % 3600 // 60
        s = seconds % 3600 % 60
        return '{:02d}:{:02d}:{:02d}'.format(h, m, s)

    for i in range(seconds):
        emit(hms(seconds-i),broadcast=True)
        emit.sleep(1)

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

This is my client-side javascript code:

<!DOCTYPE html>

<html>
    <body>
        <script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js" integrity="sha256-yr4fRk/GU1ehYJPAs8P4JlTgu0Hdsp4ZKrx8bDEDC3I=" crossorigin="anonymous"></script>
        <script type="text/javascript" charset="utf-8">
            var socket = io().connect('http://127.0.0.1:5000');
            socket.on('test_timer', function(receiving_data) {
            console.log(receiving_data);
            });
        </script>
    </body>
</html>

Even if I run the server, console.log doesn't print any timer data in client-side.

1
  • The main problem is that your client-side is never sending test_timer to the server; all you're doing is setting up a reaction to that message on both sides, but you're never emitting it anywhere. Commented Jul 24, 2020 at 9:48

1 Answer 1

2

The below lines show the signature for the emit function

   def emit(self, event, data=None, room=None, include_self=True,
             namespace=None, callback=None):

In your Flask app, you have a handler registered for test_timer event. In this handler, you need to emit a response event followed by data and not just data. For example,

@socketio.on('test_timer')
def Timer(seconds=3600):
    def hms(seconds): # hour minute second function
        h = seconds // 3600
        m = seconds % 3600 // 60
        s = seconds % 3600 % 60
        return '{:02d}:{:02d}:{:02d}'.format(h, m, s)

    for i in range(seconds):
        emit('test_timer_reply', hms(seconds-i),broadcast=True)
        socketio.sleep(1)

In your client side code, you also need to emit test_timer and register a listener for test_timer_reply.

var socket = io().connect('http://127.0.0.1:5000');
socket.emit('test_timer')
socket.on('test_timer_reply', function(receiving_data) {
  console.log(receiving_data);
});
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks a lot, works successfully but when one time send data, the for loop breaks. How can I prevent this?
Put it in a while True loop to keep sending if that's what you meant @skipsbiceps
It works successfully, but the timer restarts when the page is refreshed. why?? my broadcast option is True
It just outputting bad request 400. I have completed the changes mentioned but still not successful. Any suggestions?
I have solved the bad request by uninstalling Flask-SocketIO,python-engineio,python-socketio and then re-installing and restarting machine. Make sure you re-install the following versions Flask-SocketIO==4.3.1 python-engineio==3.13.2 python-socketio==4.6.0 . I have successfully ran this example. However, when I use the same set up to update a chart, it requires a reload stackoverflow.com/questions/68376011/… . @Oluwafemi Sule any suggestions?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.