admin管理员组文章数量:1323200
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 / oute 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/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare/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);
});
});
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 / oute 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./jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare./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);
});
});
Share
Improve this question
edited Feb 7, 2020 at 7:01
FireHawk2300
asked Feb 6, 2020 at 7:23
FireHawk2300FireHawk2300
973 silver badges14 bronze badges
3 Answers
Reset to default 6 +50You 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./ajax/libs/socket.io/2.3.0/socket.io.js"></script>
<script src="https://cdnjs.cloudflare./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>
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 remend you use one.
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);
});
本文标签: javascriptAsynchronous server messages with python flaskStack Overflow
版权声明:本文标题:javascript - Asynchronous server messages with python flask - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742089965a2420204.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论