Search code examples
pythonwebsockettornado

How can I send message to clients every x seconds when running a tornado server?


I have Python code like this:

class WebSocketHandler(tornado.websocket.WebSocketHandler):
    def check_origin(self, origin):
        print "origin: " + origin
        return True
    # the client connected
    def open(self):
        print "New client connected"
        self.write_message("You are connected")
    # the client sent the message
    def on_message(self, message):
        print "message: " + message
        self.write_message(message)
    # client disconnected
    def on_close(self):
        print "Client disconnected"

socket = tornado.web.Application([(r"/wss", WebSocketHandler),])
if __name__ == "__main__":
    socket.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

while True:
    readmydata()
    #send message to all connected clients
    time.sleep(3)

How can I start the websocket server, but continue with the python code that sends the message to all connected clients? The script blocks at tornado.ioloop.IOLoop.instance().start(), so my while True loop never runs.


Solution

  • You can use tornado.ioloop.IOLoop.add_timeout to call a method every X number of seconds from within the Tornado event loop. To send a message to all conncected clients, you'll need to maintain a global list of each connected client, which you update on each connection/disconnection.

    clients = []
    
    class WebSocketHandler(tornado.websocket.WebSocketHandler):
        def check_origin(self, origin):
            print "origin: " + origin
            return True
        # the client connected
        def open(self):
            print "New client connected"
            self.write_message("You are connected")
            clients.append(self)
    
        # the client sent the message
        def on_message(self, message):
            print "message: " + message
            self.write_message(message)
    
        # client disconnected
        def on_close(self):
            print "Client disconnected"
            clients.remove(self)
    
    def send_message_to_clients():
        try:
            read_my_data()
            for client in clients:
                # Do whatever
        finally:
            tornado.ioloop.IOLoop.instance().add_timeout(timedelta(seconds=3),
                                                         send_message_to_clients)
    
    socket = tornado.web.Application([(r"/wss", WebSocketHandler),])
    if __name__ == "__main__":
        socket.listen(8888)
        tornado.ioloop.IOLoop.instance().add_timeout(timedelta(seconds=3),
                                                     send_message_to_clients)
        tornado.ioloop.IOLoop.instance().start()