
from collections import defaultdict


# Mapping of channels to lists of socket session IDs subscribed.
CHANNELS = defaultdict(list)


class ChanneledSocketIOProtocol(object):
    """
    Proxy object for SocketIOProtocol that adds channel subscription
    and broadcast.
    """

    def __init__(self, socket):
        """
        Store the original socket protocol object.
        """
        self.socket = socket
        self.channels = [] # store our subscribed channels for faster lookup.

    def subscribe(self, channel):
        """
        Add the channel to this socket's channels, and to the list of
        subscribed session IDs for the channel. Return False if
        already subscribed, otherwise True.
        """
        if channel in self.channels:
            return False
        CHANNELS[channel].append(self.socket.session.session_id)
        self.channels.append(channel)
        return True

    def unsubscribe(socket, channel):
        """
        Remove the channel from this socket's channels, and from the
        list of subscribed session IDs for the channel. Return False
        if not subscribed, otherwise True.
        """
        try:
            CHANNELS[channel].remove(self.socket.session.session_id)
            self.channels.remove(channel)
        except ValueError:
            return False
        return True

    def broadcast_channel(self, message, channel=None):
        """
        Send the given message to all subscribers for the channel
        given. If no channel is given, send to the subscribers for
        all the channels that this socket is subscribed to.
        """
        if channel in self.channels:
            channels = [channel]
        else:
            channels = self.channels
        for channel in channels:
            for subscriber in CHANNELS[channel]:
                if subscriber != self.socket.session.session_id:
                    self._write(message, self.socket.handler.server.sessions[subscriber])

    def log(self, message):
        self.socket.handler.server.log.write(message + "\n")

    def __getattr__(self, name):
        """
        Proxy missing attributes to the socket.
        """
        return getattr(self.socket, name)

@@ -2007,24 +2007,101 @@
 , message):%0A
+        %22%22%22%0A        Logging shortcut to the server's log method.%0A        %22%22%22%0A
         self

Use the server's log method.