I\'m trying to set up a small example of a public Twitter stream over websockets. This is my websocket.py, and it\'s working.
What I\'m wondering is: how can I inte
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.
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 datetime
def 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.path
import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web
# websocket
class 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 datetime
if __name__ == "__main__":
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8888)
tornado.ioloop.IOLoop.instance().start()