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