Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

175
Views
Asynchronous server messages with python flask

I'm trying to get server messages pushed out to the end user that's logged into our flask website.

I've done some research and it seems that the best solution is to use socket-io.

My attempts at this don't seem to be working, I must also indicate that my knowledge of javascript is very basic.

Any assistance / guidance will be highly appreciated.

See my code below:

python - app.py

from flask_socketio import SocketIO, emit
from flask import Flask, render_template, url_for, request
from time import sleep

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
app.config['DEBUG'] = True

# turn the flask app into a socketio app
socketio = SocketIO(app, async_mode=None, logger=True, engineio_logger=True)

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        if request.form['submit_button'] == 'Do Stuff':
            # server doing things....
            # the below method will make calls to emit socket messages
            # based on actions / outcome of actions.
            serverActions()
    return render_template('index.html')

@socketio.on('connect')
def connect():
    print('Client connected')

@socketio.on('display_message')
def displayMessage(message):
    socketio.emit('newmessage', {'message': message})
    socketio.sleep(2)

def serverActions():
    # get connection to DB
    message = "connecting to DB"
    # show message to user on flask page
    displayMessage(message)

    # test successful connection to DB
    message = "successfully connected to DB"
    displayMessage(message)

    # query the DB
    message = "querying the DB"
    displayMessage(message)

    # update DB
    message = "updating the DB"
    displayMessage(message)

    # etc......

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

HTML - templates/index.html

<!DOCTYPE html>
<html>
<head>
    <script src="//code.jquery.com/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
    <script src="static/js/application.js"></script>
</head>
<body>
  <form method="POST">
  <div>
    <div>
      <h1>Asynchronous Flask Communication</h1>
      <p>Messages generated by the Flask server should appear below, asynchronously.</p>
    </div>
  </div>

  <div>
      <p>Asynchronous page updates will appear here:</p>
      <div>
        <input type="submit" value="Do Stuff" name="submit_button">
      </div>
      <div>
        <h3>Server Messages:</h3>
        <div id="message">
        </div>
      </div>
  </div>

  </form>
</body>
</html>

javascript - static/js/application.js

$(document).ready(function(){
    //connect to the socket server.
    var socket = io.connect('http://' + document.domain + ':' + location.port);

    //receive message details from server
    socket.on('display_message', function(msg) {
        console.log("Received message" + msg.message);
        message_string = '<p>' + msg.message + '</p>';
        $('#message').html(message_string);
    });

});
over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

You emit events that you listen for with on event handler. Also I don't think it makes sense for your event listener display_message to be inside a rest endpoint. Here is a solution with pypubsub for convenience so you can easily subscribe for all events on the server. It can work without it too but here it is

server.py

from flask_socketio import SocketIO, emit
from flask import Flask, render_template, url_for, request
from time import sleep
from pubsub import pub


app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
app.config['DEBUG'] = True

# turn the flask app into a socketio app
socketio = SocketIO(app, async_mode=None, logger=True, engineio_logger=True)

def listener(arg1):
    print('Function listener1 received:')
    print('  arg1 =', arg1)
    socketio.emit('newmessage',{'message':arg1})


pub.subscribe(listener, 'rootTopic')

@app.route('/', methods=['GET', 'POST'])
def index():
    return render_template('index.html')

@app.route('/post', methods=['POST'])
def post():
    pub.sendMessage('rootTopic', arg1='post')

@socketio.on('connect')
def connect():
    pub.sendMessage('rootTopic', arg1='connected to socket')
    print('Client connected')



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

index.html

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <div id="message"></div>
    <button id="btn">CLICK</button>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script>
$(document).ready(function(){
    //connect to the socket server.
    var socket = io.connect('http://' + document.domain + ':' + location.port);
    $('#btn').on('click', function() {
      fetch('http://' + document.domain + ':' + location.port + '/post', {method:"POST"})
    })
    //receive message details from server
    socket.on('newmessage', function(msg) {
        console.log("Received message" + msg.message);
        message = '<p>' + msg.message + '</p>';

        $('#message').append(message);
    });

});
    </script>
  </body>
</html>
over 4 years ago · Santiago Trujillo Report

0

The problem from the example that you have given appears to be that the client, i.e. your JS in the browser, is listening for the event display_message. However your server is not emitting that event by the looks of it. Every call to the displayMethod is emitting a newmessage event. Update your client to add an event listener for that event.

    socket.on('newmessage', function(msg) {
        console.log("Received message" + msg.message);
        message_string = '<p>' + msg.message + '</p>';
        $('#message').html(message_string);
    });

over 4 years ago · Santiago Trujillo Report

0

Heres the trick to it: emit messages to a group. So, could invoke join group and add everyone to a group on log in that way you can send messages to everyone connected.

from flask import Flask
from flask_socketio import SocketIO, send, emit, join_room, leave_room

app = Flask('__name__')
socket = SocketIO(app, cors_allowed_origins="*", SameSite=None)


@socket.on('connect', namespace='/optional')
def connect():
    join_room('connected')

@app.route('/message')
def some_name():
    emit('message', 'your actual message', room='connected', namespace='/optional')

Now when you hit the url it should send a message to everyone connected. Remember the namespace is optional, but i recommend you use one.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!