Example #1
0
class Handler(RequestHandler):
    @asynchronous
    def get(self):
        self.client = Client()
        self.client.connect()
        self.client.subscribe("foo", callback=self.on_receive)

    def on_receive(self, msg):
        """ New message, close out connection. """
        msg_type, msg_channel, msg = msg
        if msg_type == "message":
            self.finish({"message": msg})
Example #2
0
class Handler(RequestHandler):
    @asynchronous
    def get(self):
        self.client = Client()
        self.client.connect()
        self.client.subscribe("foo", callback=self.on_receive)

    def on_receive(self, msg):
        """ New message, close out connection. """
        msg_type, msg_channel, msg = msg
        if msg_type == b"message":
            self.finish({"message": msg.decode()})
Example #3
0
class RedisWebSocket(tornado.websocket.WebSocketHandler):

    client = None
    user = None
    channel = None
    io_loop = tornado.ioloop.IOLoop.instance()

    def open(self):
        # Get user and channel
        self.user = self.get_argument('user', None)
        self.channel = self.get_argument('channel', None)

        # new access
        self.application.db.access.insert_one(Access.connect(self.user,self.channel).__dict__)

        # get all messages
        messages = self.application.db.messages.find({"channel" : self.channel}).sort("$natural",pymongo.DESCENDING)

        output = [format_entity(msg) for msg in messages]

        for message in reversed(output):
            self.write_message(message)

        # subscribe to channel
        self.client = ToRedisClient()
        self.client.connect(host="redis")
        self.client.subscribe(self.channel, callback=self.on_receive)

    def on_receive(self,msg):
        msg_type, msg_channel, msg = msg
        if msg_type == b"message":
            self.write_message(eval(msg))
        # client.write_message(message)

    def on_message(self, message):
        entity = Message.from_dict(json.loads(message))
        self.application.db.messages.insert_one(entity.__dict__)

        conn = ToRedisClient()
        conn.connect(host="redis")

        def publish_message(channel,message):
            conn.publish(channel,message)

        self.io_loop.add_timeout(time.time(), partial(publish_message,self.channel,format_entity(entity.__dict__)))
        # self.application.manager.notify(entity.channel,format_entity(entity.__dict__))

    def on_close(self):
        self.application.db.access.insert_one(Access.disconnect(self.user, self.channel).__dict__)
        self.client.unsubscribe(self.channel)
Example #4
0
class MessageHandler(WebSocketHandler):
    def __init__(self, *args, **kwargs):
        super(MessageHandler, self).__init__(*args, **kwargs)
        self.r_server = Redis()
        self.redis = Client()
        self.redis.connect()

    def get_current_user(self):
        user = self.get_secure_cookie("user")
        if user is None:
            return ''
        else:
            return user.strip('" ')

    def on_message(self, msg):
        msginfo = loads(msg)
        # listens for handshake from page
        self.channel = msginfo['user']
        # need to split the rest off to new func so it can be asynchronous
        self.listen()

    def listen(self):
        # runs task given, with the yield required to get returned value
        # equivalent of callback/wait pairing from tornado.gen
        self.redis.subscribe(self.channel, callback=self.callback)
        # fight race condition by loading from redis after listen started
        oldmessages = self.r_server.lrange('%s:messages' % self.channel, 0, -1)
        if oldmessages is not None:
            for message in oldmessages:
                self.write_message(message)

    def callback(self, msg):
        if msg[0] == 'message':
            self.write_message(msg[2])

    @engine
    def on_close(self):
        yield Task(self.redis.unsubscribe, self.channel)
        self.redis.disconnect()
Example #5
0
class ChatSocketHandler(UserMixin, tornado.websocket.WebSocketHandler):
    cache_size = 30
    commands_client = Client()
    pub_client = Client()

    def open(self):
        # FIXME: make chat_channel dynamic
        self.chat_channel = "chat"

        self.chat_userset = chat_userset_key(self.chat_channel)
        self.from_user = self.get_current_user()['name']

        host, port = options.redis.split(":")
        self.sub_client = Client()
        self.sub_client.connect(host, int(port))
        logging.debug("Opened subscribe connection to redis for user=%s",
                      self.from_user)

        # first add entered user in user_set, then subscribe to notifications
        def sadd_finished(resp):
            self.sub_client.subscribe(self.chat_channel,
                                      callback=self.on_redis_message)

        self.sub_client.sadd(self.chat_userset,
                             self.from_user,
                             callback=sadd_finished)

        logging.info("%s joined the chat", self.from_user)
        ChatSocketHandler.send_message(self.chat_channel,
                                       self.from_user,
                                       "joined the chat",
                                       system=True)

    def on_redis_message(self, msg):
        msg_type, msg_channel, msg = msg
        logging.debug("Got message from Redis: type=%s, channel=%s, msg=%s",
                      msg_type, msg_channel, msg)
        if msg_type == b"message":
            # write message back to websocket
            self.write_message(json.loads(msg.decode()))

    def on_close(self):
        logging.info("%s left the chat", self.from_user)

        self.sub_client.srem(self.chat_userset, self.from_user)
        ChatSocketHandler.send_message(self.chat_channel,
                                       self.from_user,
                                       "left the chat",
                                       system=True)

    def on_message(self, message):
        logging.info("got message %r", message)
        ChatSocketHandler.send_message(self.chat_channel, self.from_user,
                                       message)

    @classmethod
    def update_lastmessages(cls, chat_channel, chat):
        cls.pub_client.lpush(chat_lastmessages_key(chat_channel),
                             json.dumps(chat))
        cls.pub_client.ltrim(chat_lastmessages_key(chat_channel), 0,
                             cls.cache_size)

    @classmethod
    def last_messages(cls, chat_channel, callback):
        """get last messages"""
        if not cls.commands_client.is_connected():
            host, port = options.redis.split(":")
            cls.commands_client.connect(host, int(port))
            logging.debug("Opened commands connection to redis")

        def transform(response):
            json_resp = [json.loads(x.decode("utf8")) for x in response]
            callback(json_resp[::-1])

        cls.commands_client.lrange(chat_lastmessages_key(chat_channel),
                                   0,
                                   cls.cache_size,
                                   callback=transform)

    @classmethod
    def current_users(cls, chat_channel, callback):
        """get last messages"""
        if not cls.commands_client.is_connected():
            host, port = options.redis.split(":")
            cls.commands_client.connect(host, int(port))
            logging.debug("Opened commands connection to redis")

        def transform(response):
            json_resp = [x.decode("utf8") for x in response]
            callback(json_resp)

        cls.commands_client.smembers(chat_userset_key(chat_channel),
                                     callback=transform)

    @classmethod
    def send_message(cls, chat_channel, from_user, body, system=False):
        if not cls.pub_client.is_connected():
            host, port = options.redis.split(":")
            cls.pub_client.connect(host, int(port))
            logging.debug("Opened publish connection to redis")

        if not system:
            body = message_beautify(body)

        chat_msg = {
            "id": str(uuid.uuid4()),
            "from": from_user,
            "when": datetime.now().strftime("%Y-%m-%d %H:%M"),
            "body": body,
            "system": system,
        }

        cls.update_lastmessages(chat_channel, chat_msg)
        logging.debug("Broadcasting message %s", chat_msg)
        cls.pub_client.publish(chat_channel, json.dumps(chat_msg))
Example #6
0
    if message_type == 'landing:track:change':
        for participant in RouterConnection.participants:
            if participant.user_id == 'anonymous':
                participant.send(message_data)

    elif message_type == 'admin:':
        user_id = data.get('user_id', None)
        for participant in RouterConnection.participants:
            if participant.user_id == user_id:
                participant.send(message_data)

application = tornado.web.Application(
    sockjs.tornado.SockJSRouter(RouterConnection, '/sock').urls
)


if __name__ == '__main__':
    parse_command_line()
    import logging
    logging.getLogger().setLevel(logging.DEBUG)

    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(options.port, address=options.host)

    client = Client()
    client.connect()
    client.subscribe('tornado_events', callback=tornado_events)

    tornado.ioloop.IOLoop.instance().start()
Example #7
0
class ChatSocketHandler(UserMixin, tornado.websocket.WebSocketHandler):
    cache_size = 30
    commands_client = Client()
    pub_client = Client()

    def open(self):
        # FIXME: make chat_channel dynamic
        self.chat_channel = "chat"

        self.chat_userset = chat_userset_key(self.chat_channel)
        self.from_user = self.get_current_user()['name']

        host, port = options.redis.split(":")
        self.sub_client = Client()
        self.sub_client.connect(host, int(port))
        logging.debug("Opened subscribe connection to redis for user=%s", self.from_user)

        # first add entered user in user_set, then subscribe to notifications
        def sadd_finished(resp):
            self.sub_client.subscribe(self.chat_channel, callback=self.on_redis_message)
        self.sub_client.sadd(self.chat_userset, self.from_user, callback=sadd_finished)

        logging.info("%s joined the chat", self.from_user)
        ChatSocketHandler.send_message(self.chat_channel, self.from_user, "joined the chat", system=True)

    def on_redis_message(self, msg):
        msg_type, msg_channel, msg = msg
        logging.debug("Got message from Redis: type=%s, channel=%s, msg=%s", msg_type, msg_channel, msg)
        if msg_type == b"message":
            # write message back to websocket
            self.write_message(json.loads(msg.decode()))

    def on_close(self):
        logging.info("%s left the chat", self.from_user)

        self.sub_client.srem(self.chat_userset, self.from_user)
        ChatSocketHandler.send_message(self.chat_channel, self.from_user, "left the chat", system=True)

    def on_message(self, message):
        logging.info("got message %r", message)
        ChatSocketHandler.send_message(self.chat_channel, self.from_user, message)

    @classmethod
    def update_lastmessages(cls, chat_channel, chat):
        cls.pub_client.lpush(chat_lastmessages_key(chat_channel), json.dumps(chat))
        cls.pub_client.ltrim(chat_lastmessages_key(chat_channel), 0, cls.cache_size)

    @classmethod
    def last_messages(cls, chat_channel, callback):
        """get last messages"""
        if not cls.commands_client.is_connected():
            host, port = options.redis.split(":")
            cls.commands_client.connect(host, int(port))
            logging.debug("Opened commands connection to redis")

        def transform(response):
            json_resp = [json.loads(x.decode("utf8")) for x in response]
            callback(json_resp[::-1])

        cls.commands_client.lrange(chat_lastmessages_key(chat_channel), 0, cls.cache_size, callback=transform)

    @classmethod
    def current_users(cls, chat_channel, callback):
        """get last messages"""
        if not cls.commands_client.is_connected():
            host, port = options.redis.split(":")
            cls.commands_client.connect(host, int(port))
            logging.debug("Opened commands connection to redis")

        def transform(response):
            json_resp = [x.decode("utf8") for x in response]
            callback(json_resp)

        cls.commands_client.smembers(chat_userset_key(chat_channel), callback=transform)

    @classmethod
    def send_message(cls, chat_channel, from_user, body, system=False):
        if not cls.pub_client.is_connected():
            host, port = options.redis.split(":")
            cls.pub_client.connect(host, int(port))
            logging.debug("Opened publish connection to redis")

        if not system:
            body = message_beautify(body)

        chat_msg = {
            "id": str(uuid.uuid4()),
            "from": from_user,
            "when": datetime.now().strftime("%Y-%m-%d %H:%M"),
            "body": body,
            "system": system,
            }

        cls.update_lastmessages(chat_channel, chat_msg)
        logging.debug("Broadcasting message %s", chat_msg)
        cls.pub_client.publish(chat_channel, json.dumps(chat_msg))