def _release_chanel_handler(self):
        """
        释放超时消息

        :return:
        """
        current_time = time.time()
        loop_count = 1

        for receive_id in self.sub_dicts.keys():
            (chanel_id, start_time, handler) = self.sub_dicts[receive_id]
            diff_time = current_time - start_time
            loop_count += 1
            if loop_count > self.loop_count:
                logger.warn("loop count exceed %d for _release_chanel_handler", self.loop_count)
                break

            #
            # 连接已经关闭
            #
            if handler == None or handler.request.connection.stream._closed == True:
                logger.info("remove closed sub chanel id:%s", chanel_id)
                self.unsubscribe(receive_id)
                continue
            if diff_time > self.pubsub_timeout:
                self.unsubscribe(receive_id)
                continue

            pass
    def subscribe(self, handler, chanel_id, receiver):
        """
        @summary: 针对制定频道发布消息

        @param chanel_id: 频道ID
        @param body: 需要发布的内容
        @return:
        """
        message_list = self.chanel_message.get(chanel_id, [])
        if len(message_list) > 0:
            logger.info("have old %d messages", len(message_list))
            (message, start) = message_list.pop()
            tornado.ioloop.IOLoop.instance().add_callback(
                callback=lambda: receiver(chanel_id, message=message))
            return 0
            
        receiver_id = sig_pub_sub.connect(
            receiver,
            chanel_id)

        #
        # 记录到字典中
        #
        old_str, _, _ = self.sub_dicts.get(receiver_id, (" ", 0, None))
        self.sub_dicts[receiver_id] = (old_str + " " + chanel_id, time.time(), handler)
        return receiver_id
    def pubish(self, chanel_id, body, from_redis=False):
        """
        @summary: 针对制定频道发布消息

        @param chanel_id: 频道ID
        @param body: 需要发布的内容
        @return:
        """
        if from_redis is False and self.redis_pub:
            redis_message = {
                "chanel_id": chanel_id,
                "message": body}
            self.redis_pub.publish(self.REDIS_PUBSU_CHANEL_ID, json.dumps(redis_message))
            return [chanel_id]

        #
        # 广播消息内容
        #
        receivers = sig_pub_sub.send(
            chanel_id,
            message=body)
            
        #
        # 检查是否拥有对应的接受者,如果有则不保留对应的内容
        #
        if len(receivers) <= 0:
            message_list = self.chanel_message.get(chanel_id, [])
            message_list.append((body, time.time()))
            self.chanel_message[chanel_id] = message_list

        logger.info("have %d receivers", len(receivers))
        return receivers
 def get(self, message_id):
     logger.info("received %s sub request", message_id)
     self.message_id = message_id
     #
     # 重置连接关闭回调函数
     #
     if getattr(self.request, "connection", None):
         self.request.connection.set_close_callback(
             self.on_connection_close)
     self.receive_id = self.application.pub_sub.subscribe(
         self,
         self.message_id,
         self.on_message)
Exemple #5
0
def main():
    #
    # 首先解析默认参数
    #
    parse_command_line()

    config_path = options.config
    if not config_path:
        config_path = os.path.join(os.path.dirname(__file__), "pubsub.ini")

    try:
        #
        # 读取配置文件
        #
        config.read(config_path)
    except:
        logger.warning("Invalid config path:%s", config_path)
        return

    root_path = os.path.dirname(os.path.abspath(__file__))
    root_path = os.path.join(root_path, "cache")
    #
    # settings
    #
    settings = {
        'debug'         : False,  # True允许自加载,便于运行中修改代码
        'static_path'   : os.path.join(os.path.dirname(__file__), "www", "statics"),
        'template_path' : os.path.join(os.path.dirname(__file__), "www", "templates"),
        'root_path'     : root_path,
        "xheaders"      : True,
    }
    handlers = [
        (r"/(favicon\.ico)", tornado.web.StaticFileHandler, dict(path=settings['static_path'])),
        (r"/statics/(.*)/?", tornado.web.StaticFileHandler, dict(path=settings['static_path'])),
        ]

    tornado_app = SEApplication(
        handlers=handlers,
        **settings
        )

    logger.info("begin to start server on port:%d", options.port)
    global http_server
    http_server = HTTPServer(tornado_app)

    try:
        http_server.listen(options.port)
    except Exception, ex:
        logger.warn("listen port:%d failed with:%s", options.port, str(ex))
        return
 def handle_subs(self):
     #
     # 重置连接关闭回调函数
     #
     if getattr(self.request, "connection", None):
         self.request.connection.set_close_callback(
             self.on_connection_close)
     chanel_ids          = self.get_argument("chanelid", '')
     logger.info("received %s subs request", chanel_ids)
     self.message_ids    = chanel_ids.split('|')
     self.receive_ids    = []
     for message_id in self.message_ids:
         receive_id = self.application.pub_sub.subscribe(
             self,
             message_id,
             self.on_message)
         self.receive_ids.append(receive_id)