Daiju
Daiju

Reputation: 11

Python-socketio: How to emit message regulary from server to client?

I want to send a message from server to client at 1 second intervals, writing the string 'send clock' to console before the message is sent.
However, client does not receive "clock" message.
I have got the echo message is working fine, so it's not a connection issue.

How can I send a message at 1 second intervals?

Server code(python):

import threading
import time
import socketio
import eventlet

socket = socketio.Server(async_mode='eventlet')
app = socketio.WSGIApp(socket)

@socket.on('echo')
def echo(sid, message):
    socket.emit('echo', message)

def worker1():
    eventlet.wsgi.server(eventlet.listen(('', 5030)), app)

def worker2():
    while(1):
        print("send clock")
        socket.emit('clock', '1 sec')
        time.sleep(1)

def main():
    t1 = threading.Thread(target=worker1)
    t2 = threading.Thread(target=worker2)
    t1.start()
    t2.start()

if __name__ == '__main__':
    main()

Client code(nodejs):

const io = require("socket.io-client");

socket = io("http://xxx.xxx.xxx.xxx:5030", {
    transports: ["websocket"],
});

socket.emit("echo", "test");

socket.on("echo", (data) => {
    console.log(data);
});

socket.on("clock", (data) => {
    console.log("receive clock");
});

My server side environment:

python: 3.7.3
python-socketio: 4.5.1
eventlet: 0.25.1

Thank you for reading it until the very end. <3

Upvotes: 1

Views: 3178

Answers (1)

Miguel Grinberg
Miguel Grinberg

Reputation: 67509

You can't combine threads or the sleep() function with eventlet, you should use greenlet based equivalents instead. The easiest way to do this is to start your background tasks with the socket.start_background_task() helper function, and sleep with socket.sleep(). I'm writing this by memory so there might be small mistakes, but your application could do something like the following:

import socketio
import eventlet

socket = socketio.Server(async_mode='eventlet')
app = socketio.WSGIApp(socket)

@socket.on('echo')
def echo(sid, message):
    socket.emit('echo', message)

def worker1():
    eventlet.wsgi.server(eventlet.listen(('', 5030)), app)

def worker2():
    while(1):
        print("send clock")
        socket.emit('clock', '1 sec')
        socket.sleep(1)

def main():
    socket.start_background_task(worker2)
    worker1()

if __name__ == '__main__':
    main()

Upvotes: 2

Related Questions