How to run functions outside websocket loop in python (tornado) How to run functions outside websocket loop in python (tornado) python python

How to run functions outside websocket loop in python (tornado)


You could call a

IOLoop.add_timeout(deadline, callback)

that calls the callback at specified deadline timeout (one shot, but you can reschedule), or use the

tornado.ioloop.PeriodicCallback if you have a more periodic task.

See: http://www.tornadoweb.org/en/stable/ioloop.html#tornado.ioloop.IOLoop.add_timeout

Update: some example

import datetimedef test():    print "scheduled event fired"...if __name__ == "__main__":    http_server = tornado.httpserver.HTTPServer(application)    http_server.listen(8888)    main_loop = tornado.ioloop.IOLoop.instance()    # Schedule event (5 seconds from now)    main_loop.add_timeout(datetime.timedelta(seconds=5), test)    # Start main loop    main_loop.start()

it calls test() after 5 seconds.

Update 2:

import os.pathimport tornado.httpserverimport tornado.websocketimport tornado.ioloopimport tornado.web# websocketclass FaviconHandler(tornado.web.RequestHandler):    def get(self):        self.redirect('/static/favicon.ico')class WebHandler(tornado.web.RequestHandler):    def get(self):        self.render("websockets.html")class WSHandler(tornado.websocket.WebSocketHandler):    def open(self):        print 'new connection'        self.write_message("Hi, client: connection is made ...")        tornado.ioloop.IOLoop.instance().add_timeout(datetime.timedelta(seconds=5), self.test)    def on_message(self, message):        print 'message received: \"%s\"' % message        self.write_message("Echo: \"" + message + "\"")        if (message == "green"):            self.write_message("green!")    def on_close(self):        print 'connection closed'    def test(self):        self.write_message("scheduled!")handlers = [    (r"/favicon.ico", FaviconHandler),    (r'/static/(.*)', tornado.web.StaticFileHandler, {'path': 'static'}),    (r'/', WebHandler),    (r'/ws', WSHandler),]settings = dict(    template_path=os.path.join(os.path.dirname(__file__), "static"),)application = tornado.web.Application(handlers, **settings)import datetimeif __name__ == "__main__":    http_server = tornado.httpserver.HTTPServer(application)    http_server.listen(8888)    tornado.ioloop.IOLoop.instance().start()


I stumbled upon similar problem. Here is my solution. Hope this will be helpful to someone out there

wss = []class wsHandler(tornado.websocket.WebSocketHandler):    def open(self):        print 'Online'        if self not in wss:            wss.append(self)    def on_close(self):        print 'Offline'        if self in wss:            wss.remove(self)def wsSend(message):    for ws in wss:        ws.write_message(message)

To send message to your websockets simply use this:

wsSend(message)

wsSend update

I've been getting exceptions with wsSend once in a while. In order to fix it I've modified code a bit to following:

def wsSend(message):    for ws in wss:        if not ws.ws_connection.stream.socket:            print "Web socket does not exist anymore!!!"            wss.remove(ws)        else:            ws.write_message(message)


One way to also do this is to use a pub-sub module.

Meaning you have your connections subscribe to it, and rather than setting timeouts for every single connection, you just set one timeout to publish after said period of time.

Probably one of the most implemented is redis. There are also some modules specifically for tornado: toredis or brükva for example.

Of course this might not be necessary for just a simple page, but scales really well and is also very nice to maintain/extend once you've set it up.