Emitting from regular route to handle server updates #1835
-
If at any moment seeing the full project could prove useful it can be found here I have an html form that takes in a txt file, on route dashboard: @app.route("/dashboard", methods=['GET', 'POST'])
@login_required
def dashboard():
return render_template("dashboard.html") The form has nothing too special about it beyond some css and js to make it look pretty. <form action = "/display" method = "POST"
enctype = "multipart/form-data" class = "file-upload-form">
<h2>Land Calculator</h2>
<h6>Deck list as a txt file</h6>
<div class="drop-zone">
<span class="drop-zone__prompt">Drag your deck file or click to chose one</span>
<input type="file" name="file" class="drop-zone__input">
</div>
<div class = "centerbtn">
<input type = "submit" id = "SendButton" class = "btn disabled" disabled>
</div>
</form>
<script src="./static/main.js"></script> What I do is I take the information given on the txt file, processes it, use it get some web pages, scrape said pages and then display that information on a route called display. @app.route('/display', methods = ['GET', 'POST'])
def save_file():
if request.method == 'POST':
f = request.files['file']
filename = secure_filename(f.filename)
f.save(app.config['UPLOAD_FOLDER'] + filename)
colors, lands, coloridentity = gen_color_identity(filename)
#scraping mtggoldfish for decks with same color identity
list_of_decks = get_list_of_decks(coloridentity)
#counting the 5 most common non basic lands in those decks
land_list = []
for deck in list_of_decks[0:4]:
land_list.append(get_lands_list(deck))
counter = Counter()
for d in land_list:
counter.update(d)
display_info = gen_display_info(counter.most_common(6))
os.remove(app.config['UPLOAD_FOLDER'] + filename)
return render_template("display.html", display_info = display_info, colors = colors, lands = lands) This is all working fine but as you can probably imagine this takes a bit of time. So, I want to add a progress bar, using sockets to tell the client as the server is going through the steps. i added an event to dashboard.html <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
<script src="./static/chat.js"></script> chat.js var socket = io();
socket.on('client acknowledgment', function(message){
console.log("client", message);
}); And created a socket instance on the init.py and I made a simple event on a file called socket_events. from flask_socketio import emit
#dta_pkt is the name of the folder were the __init__.py is
from dta_pkt import socketio
@socketio.on('connect')
def user_conecting():
print("server acknowledgment")
emit("client acknowledgment", "acknowledgment") So now when I go into the dashboard route, I can see both acknowledgements, so everything seems to be working. Then I tried making the same emit from the route.py file by importing the same socketio instance that i used on the socket_events file and emitting on the display route after every step. #dta_pkt is the folder where all my files and modules live
from dta_pkt.socket_events import socketio
@app.route('/display', methods = ['GET', 'POST'])
def save_file():
if request.method == 'POST':
f = request.files['file']
filename = secure_filename(f.filename)
f.save(app.config['UPLOAD_FOLDER'] + filename)
colors, lands, coloridentity = gen_color_identity(filename)
socketio.emit("client acknowledgment", "colorIdentity Done")
#scraping mtggoldfish for decks with same color identity
list_of_decks = get_list_of_decks(coloridentity)
socketio.emit("client acknowledgment", "listOfDecks Done")
#counting the 5 most common non basic lands in those decks
land_list = []
for deck in list_of_decks[0:4]:
land_list.append(get_lands_list(deck))
counter = Counter()
for d in land_list:
counter.update(d)
socketio.emit("client acknowledgment", "landList Done")
display_info = gen_display_info(counter.most_common(6))
socketio.emit("client acknowledgment", "All Done")
os.remove(app.config['UPLOAD_FOLDER'] + filename)
return render_template("display.html", display_info = display_info, colors = colors, lands = lands) But i don’t get any updates. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
A Socket.IO connection cannot be preserved across pages. When you are in the Socket.IO applications are normally single-page apps. You may want to consider submitting your form via a background request, so that your socket connection isn't interrupted. |
Beta Was this translation helpful? Give feedback.
A Socket.IO connection cannot be preserved across pages. When you are in the
POST
route handler the browser is closing the page, and will only display a new page when this route returns a response. Only at this point the browser will make a new Flask-SocketIO connection.Socket.IO applications are normally single-page apps. You may want to consider submitting your form via a background request, so that your socket connection isn't interrupted.