Is it possible to send a message to all active WebSocket connections? Using either node.js or python tornado websockets Is it possible to send a message to all active WebSocket connections? Using either node.js or python tornado websockets node.js node.js

Is it possible to send a message to all active WebSocket connections? Using either node.js or python tornado websockets


socket.io solution:

// note, io.listen() will create a http server for youvar io = require('socket.io').listen(80);io.sockets.on('connection', function (socket) {  io.sockets.emit('this', { will: 'be received by everyone' });  socket.on('private message', function (msg) {    console.log('I received a private message from ', socket.id, ' saying ', msg);    // Echo private message only to the client who sent it    socket.emit('private message', msg);  });  socket.on('disconnect', function () {    // This will be received by all connected clients    io.sockets.emit('user disconnected');  });});all_active_connections = {};

webocket server (there are many), do same manually:

  var ws = require("ws");  global_counter = 0;  all_active_connections = {};  ws.createServer(function (websocket)   {      websocket.on('connect', function()       {          var id = global_counter++;          all_active_connections[id] = websocket;          websocket.id = id;       }).on('data', function (data) {          if (data == 'broadcast me!')          {              for (conn in all_active_connections)                 all_active_connections[conn].write(data);          }             }    }).on('close', function() {        delete all_active_connections[websocket.id];    });  }).listen(8080);


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')


This redis + websockets (on tornado) example should help you. Basically you have a list of listeners who should be notified and as soon as a message is received iterate through that list and inform them.