I’ve build a test app (testing for RESTfull Api) to process some POST requests from another app.
When both apps are run localy from PyCharm everything works ok – POST request activates a function which a frontend socketIO is monitoring, and thus triggering a Frontend element update.
My main goal is, however, to have some clients that run localy which will be sending POST requests to a server app in the cloud (Koyeb).
The platform needs to be run using Gunicorn WSGI server, and how ever I try to make it run, the socketIO part just wont work. POST requests are getting through and activate the required function, but socketIO doesn’t work.
app.py code:
import eventlet
eventlet.monkey_patch()
from flask import Flask, render_template, request, redirect, send_file, url_for, jsonify
from flask_sqlalchemy import SQLAlchemy
import secrets, os, requests, json
from flask_login import LoginManager, UserMixin, login_user, logout_user, current_user, login_required
from flask_bcrypt import Bcrypt
import feedparser
from flask_socketio import SocketIO, emit
app = Flask(__name__)
socketio = SocketIO(app, async_mode='eventlet')
#
#other code
#
@app.route("/endpoint", methods=['GET', 'POST'])
def endpoint():
if request.method == 'POST':
#ApiDb.__table__.drop(db.engine)
#db.session.query(ApiDb).delete()
# dbVisits2 = db.session.query(ApiDb).filter_by(id=1).first()
try:
dbVisits = ApiDb.query.filter_by(id=1).first()
dbVisits.nrVisits += 1
except:
db.session.add(ApiDb(id=1, nrVisits=1))
db.session.commit()
#trigger_update()
handle_trigger_update()
return {'odgovor': 'OK'}
@socketio.on('trigger_update')
def handle_trigger_update():
dbVisits = ApiDb.query.filter_by(id=1).first()
total = dbVisits.nrVisits
socketio.emit('update', {'total': total})
@app.route('/trigger_backend')
def trigger_backend():
handle_trigger_update() # Poziv backend funkcije direktno
return 'Backend function triggered successfully'
if __name__=='__main__':
#socketio.run(app, debug=True, allow_unsafe_werkzeug=True)
#socketio.run(app)
#socketio.run(app, port=8000)
wsgi.server(eventlet.listen(('', 8000)), app)
html code:
<!DOCTYPE html>
<html lang="hr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %} Naslov {% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/w3css.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/fontawesome/css/all.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
</head>
<body>
<div class="outside-container">
<div class="form-container" style="width: clamp(600px, 30vw, 1000px);">
<h3>Comms</h3>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.3.1/socket.io.js" integrity="sha512-Y5MDU6RaF5h5HE5BgqJlKkV12kbkbIgWHutcT+XHHNOUzr+HHjWZGC02sqEguuPglmFms3cc08WH2PhQ5rF8Cw==" crossorigin="anonymous"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
const socket = io.connect('http://' + document.domain + ':' + location.port, {
transports: ['websocket']
});
console.log('sckIO start');
socket.on('update', function(data) {
console.log('sckIO update');
document.getElementById('output3').innerText = data.total;
});
function triggerBackend() {
fetch('/trigger_backend')
.then(response => response.text())
.then(data => console.log(data)) // Log the response from the server
.catch(error => console.error('Error:', error));
}
triggerBackend();
});
</script>
<div style="display: flex; justify-content: center;">
Number of visits - periodicaly: <strong><div style="margin-left: 15px;" id="output"></div></strong>
</div>
<div style="display: flex; justify-content: center;">
Number of visits - onStart: <strong><div style="margin-left: 15px;" id="output2"></div></strong>
</div>
<div style="display: flex; justify-content: center;">
Number of visits - direct from userComm load: <strong><div style="margin-left: 15px;">{{ total }}</div></strong>
</div>
<div style="display: flex; justify-content: center;">
Number of visits - SocketIO: <strong><div style="margin-left: 15px;" id="output3"></div></strong>
</div>
</div>
</div>
</body>
</html>
Koyeb buildpack run command override: (Procfile)
gunicorn --worker-class eventlet -w 1 app:app
Anyone have some idea? It doesnt matter if it uses eventlet or gunicorn, I just want the socketIO to work