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 pong
Que 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)