1

I would like to have users create and join a "rooms" so that they can collaborate.

I'm looking at SockJs Multiplexer server and wondering if I can leverage some of that to create and broadcast to specific channel/room.

In the example, a channel is created manually and client connects to that channel.

Would treating these channels as rooms work?

Is there a way to dynamically create these channels instead of manually declaring them on server?

Martin Thorsen Ranang
  • 2,394
  • 1
  • 28
  • 43
dev.e.loper
  • 35,446
  • 76
  • 161
  • 247

1 Answers1

3

Disclaimer: I didn't notice that you were referring to the Javascript-version of the server until I had written my answer. Therefore, my code examples are given using the Python-based sockjs-tornado, but I guess the principles should be the same.

Yes, you may treat the channels as rooms by keeping a set of referenced connections in each SockJSConnection-derived class. To do that, all you would need is to change each connection class slightly from

class AnnConnection(SockJSConnection):
    def on_open(self, info):
        self.send('Ann says hi!!')

    def on_message(self, message):
        self.broadcast(self.connected, 'Ann nods: ' + message)

to

class AnnConnection(SockJSConnection):
    connected = WeakSet()

    def on_open(self, info):
        self.connected.add(self)
        self.send('Ann says hi!!')

    def on_message(self, message):
        self.broadcast(self.connected, 'Ann nods: ' + message)

    def on_close(self):
        self.connected.remove(self)
        super(AnnConnection, self).on_close()

in server.py.

To create the channels dynamically, I changed the __main__ code and MultiplexConnection class slightly and added a couple of new classes. In the if __name__ == "__main__": block,

# Create multiplexer
router = MultiplexConnection.get(ann=AnnConnection, bob=BobConnection,
                                 carl=CarlConnection)

was changed to

# Create multiplexer
router = MultiplexConnection.get()

While

class MultiplexConnection(conn.SockJSConnection):
    channels = dict()
    # …

    def on_message(self, msg):
        # …
        if chan not in self.channels:
            return

in MultiplexConnection was changed to

class MultiplexConnection(conn.SockJSConnection):
    channels = dict()
    _channel_factory = ChannelFactory()
    # …

    def on_message(self, msg):
        # …
        if chan not in self.channels:
            self.channels[chan] = self._channel_factory(chan)

and the classes

class DynamicConnection(SockJSConnection):
    def on_open(self, info):
        self.connected.add(self)
        self.send('{0} says hi!!'.format(self.name))

    def on_message(self, message):
        self.broadcast(self.connected, '{0} nods: {1}'
            .format(self.name, message))

    def on_close(self):
        self.connected.remove(self)
        super(DynamicConnection, self).on_close()


class ChannelFactory(object):
    _channels = dict()

    def __call__(self, channel_name):
        if channel_name not in self._channels:
            class Channel(DynamicConnection):
                connected = WeakSet()
                name = channel_name

            self._channels[channel_name] = Channel

        return self._channels[channel_name]

were added to multiplex.py.

Martin Thorsen Ranang
  • 2,394
  • 1
  • 28
  • 43
  • Hi Martin, Am facing trouble making my chat interactions private (one to one). Could you kindly have a look at http://stackoverflow.com/questions/34461046/private-messaging-using-sockjs-tornado/34463050#34463050 ? – Satheesh Panduga Dec 25 '15 at 14:12
  • Thanks for reaching out, Sathish. I just wrote my [suggested solution](http://stackoverflow.com/a/34466792/126273). – Martin Thorsen Ranang Dec 25 '15 at 22:02