Tengo una pregunta muy similar a esta: enviar datos cada 10 segundos a través de socket.io
Pero: Mi servidor está escrito en Python, el cliente está en JavaScript
La meta:
ping de mensajes push del servidor cada n segundosping , el servidor transmite un mensaje pongQue funciona:
ping del cliente es recibido por el servidor, respondido con pong , que nuevamente es recibido por el clienteping_in_intervals cada 5 segundosLo que no funciona:
ping_in_intervals (lo que activa el envío de un ping ), ningún cliente recibe ese ping .ping_in_intervals está activo, las conexiones de socket fallan aproximadamente cada minuto. Si el método está comentado, la conexión del socket se mantiene estable.Observaciones:
ping_in_intervals no parece funcionar correctamente junto con el subproceso del servidor wsgi.ping_in_intervals desestabiliza el subproceso del servidor, lo que hace que se pierdan las conexiones (que se restablecen de inmediato, pero se caen cada minuto más o menos)Servidor:
import eventlet import socketio import threading sio = socketio.Server(cors_allowed_origins="*", async_mode='eventlet') app = socketio.WSGIApp(sio) def ping_in_intervals(): threading.Timer(5.0, ping_in_intervals).start() print("send ping") sio.emit('ping') @sio.on('ping') def ping(*args): print("received ping - send pong") sio.emit('pong') ping_in_intervals() eventlet.wsgi.server(eventlet.listen(('', 8080)), app)Cliente:
const socket = io.connect('localhost:8080', {secure: true, transports: ['websocket']}); socket.on('pong', () => { console.log('received pong'); }); socket.on('ping', () => { console.log('received ping'); }); socket.on('connect', () => { socket.emit('ping') });Encontré la solución en https://github.com/miguelgrinberg/python-socketio/blob/main/examples/server/wsgi/app.py#L16-L22
El subproceso, que envía mensajes del servidor cada n segundos, no debe iniciarse mediante threading , sino mediante la función start_background_task de socketio .
Aquí está el código de trabajo:
import eventlet import socketio sio = socketio.Server(cors_allowed_origins="*", async_mode='eventlet') app = socketio.WSGIApp(sio) def ping_in_intervals(): while True: sio.sleep(10) sio.emit('ping') @sio.on('ping') def ping(*args): sio.emit('pong') thread = sio.start_background_task(ping_in_intervals) eventlet.wsgi.server(eventlet.listen(('', 8080)), app)