Asynchronous server messages with python flask
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>