For a solution based on tornado/tornadio, you SocketConnection class needs to maintain a list of connections at the class level. Your on_connect handler would add the connection to this list, and on_close would remove it. For sample pseudo-code see this post by Serge S. Koval. The code is reproduce below:
Declare your TornadIO connection class:
class MyConnection(SocketConnection):
participants = set()
@classmethod
def broadcast(cls, msg):
for p in cls.participants:
p.send(msg)
@classmethod
def controller_msg(cls, msg):
cls.broadcast(msg)
In your device polling thread, do something like:
while True:
datum = file.readline()
if len(datum) > 2:
t = json.loads(datum)
...
def callback():
MyConnection.controller_msg(t)
io_loop.add_callback(callback)
Additionally, gevent-socketio has support for message broadcast, but it's based on gevent, not tornado.
UPDATE:
tornadio2 already maintains a list of active sessions, so all you need to do is:
class MyConnection(SocketConnection):
def broadcast(self, event, message):
for session_id, session in self.session.server._sessions._items.iteritems():
session.conn.emit(event, message)
This works because each connection instance has a reference to its session, which has a reference to the global router used to create the application (stored as server
), which maintains a list of sessions in a SessionContainer
object in _sessions
. Now whenever you want to broadcast a message within your connection class, just do:
self.broadcast('my_custom_event', 'my_event_args')