Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

177
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda