Exemple #1
0
 def startProvider(self, repAddress, pubAddress, interval):
     """"""
     self.mode = self.MODE_PROVIDER
     self.interval = interval
     
     if not self.server:
         self.server = RpcServer(repAddress, pubAddress)
         self.server.usePickle()
         self.server.register(self.getPos)
         self.server.start()
     
     self.writeLog(u'启动发布者模式(如需修改通讯地址请重启程序)')
Exemple #2
0
 def loadSetting(self):
     """读取配置"""
     with open(self.settingFilePath) as f:
         d = json.load(f)
         
         self.repAddress = d['repAddress']
         self.pubAddress = d['pubAddress']
         
         self.server = RpcServer(self.repAddress, self.pubAddress)
         self.server.usePickle()
         self.server.register(self.call)
         self.server.start()
    def init_server(self):
        """"""
        self.server = RpcServer()

        self.server.register(self.main_engine.subscribe)
        self.server.register(self.main_engine.send_order)
        self.server.register(self.main_engine.send_orders)
        self.server.register(self.main_engine.cancel_order)
        self.server.register(self.main_engine.cancel_orders)
        self.server.register(self.main_engine.query_history)

        self.server.register(self.main_engine.get_tick)
        self.server.register(self.main_engine.get_order)
        self.server.register(self.main_engine.get_trade)
        self.server.register(self.main_engine.get_position)
        self.server.register(self.main_engine.get_account)
        self.server.register(self.main_engine.get_contract)
        self.server.register(self.main_engine.get_all_ticks)
        self.server.register(self.main_engine.get_all_orders)
        self.server.register(self.main_engine.get_all_trades)
        self.server.register(self.main_engine.get_all_positions)
        self.server.register(self.main_engine.get_all_accounts)
        self.server.register(self.main_engine.get_all_contracts)
        self.server.register(self.main_engine.get_all_active_orders)
class RpcEngine(BaseEngine):
    """"""
    setting_filename = "rpc_service_setting.json"

    def __init__(self, main_engine: MainEngine, event_engine: EventEngine):
        """"""
        super().__init__(main_engine, event_engine, APP_NAME)

        self.rep_address = "tcp://*:2014"
        self.pub_address = "tcp://*:4102"

        self.server: Optional[RpcServer] = None

        self.init_server()
        self.load_setting()
        self.register_event()

    def init_server(self):
        """"""
        self.server = RpcServer()

        self.server.register(self.main_engine.subscribe)
        self.server.register(self.main_engine.send_order)
        self.server.register(self.main_engine.send_orders)
        self.server.register(self.main_engine.cancel_order)
        self.server.register(self.main_engine.cancel_orders)
        self.server.register(self.main_engine.query_history)

        self.server.register(self.main_engine.get_tick)
        self.server.register(self.main_engine.get_order)
        self.server.register(self.main_engine.get_trade)
        self.server.register(self.main_engine.get_position)
        self.server.register(self.main_engine.get_account)
        self.server.register(self.main_engine.get_contract)
        self.server.register(self.main_engine.get_all_ticks)
        self.server.register(self.main_engine.get_all_orders)
        self.server.register(self.main_engine.get_all_trades)
        self.server.register(self.main_engine.get_all_positions)
        self.server.register(self.main_engine.get_all_accounts)
        self.server.register(self.main_engine.get_all_contracts)
        self.server.register(self.main_engine.get_all_active_orders)

    def load_setting(self):
        """"""
        setting = load_json(self.setting_filename)
        self.rep_address = setting.get("rep_address", self.rep_address)
        self.pub_address = setting.get("pub_address", self.pub_address)

    def save_setting(self):
        """"""
        setting = {
            "rep_address": self.rep_address,
            "pub_address": self.pub_address
        }
        save_json(self.setting_filename, setting)

    def start(self, rep_address: str, pub_address: str):
        """"""
        if self.server.is_active():
            self.write_log("RPC service operation ")
            return False

        self.rep_address = rep_address
        self.pub_address = pub_address

        try:
            self.server.start(rep_address, pub_address)
        except:  # noqa
            msg = traceback.format_exc()
            self.write_log(f"RPC service failed to start :{msg}")
            return False

        self.save_setting()
        self.write_log("RPC service starts successfully ")
        return True

    def stop(self):
        """"""
        if not self.server.is_active():
            self.write_log("RPC service does not start ")
            return False

        self.server.stop()
        self.server.join()
        self.write_log("RPC service is stopped ")
        return True

    def close(self):
        """"""
        self.stop()

    def register_event(self):
        """"""
        self.event_engine.register_general(self.process_event)

    def process_event(self, event: Event):
        """"""
        if self.server.is_active():
            self.server.publish("", event)

    def write_log(self, msg: str) -> None:
        """"""
        log = LogData(msg=msg, gateway_name=APP_NAME)
        event = Event(EVENT_RPC_LOG, log)
        self.event_engine.put(event)
Exemple #5
0
class TcEngine(object):
    """交易复制引擎"""
    MODE_PROVIDER = 1
    MODE_SUBSCRIBER = 2

    #----------------------------------------------------------------------
    def __init__(self, mainEngine, eventEngine):
        """Constructor"""
        self.mainEngine = mainEngine
        self.eventEngine = eventEngine

        self.mode = None  # Subscriber/Provider
        self.posDict = defaultdict(int)  # vtPositionName:int
        self.targetDict = defaultdict(int)  # vtPositionName:int
        self.copyRatio = 1
        self.interval = 1
        self.subscribeSet = set()

        self.count = 0
        self.server = None  # RPC Server
        self.client = None  # RPC Client

        self.registerEvent()

    #----------------------------------------------------------------------
    def startProvider(self, repAddress, pubAddress, interval):
        """"""
        self.mode = self.MODE_PROVIDER
        self.interval = interval

        if not self.server:
            self.server = RpcServer(repAddress, pubAddress)
            self.server.usePickle()
            self.server.register(self.getPos)
            self.server.start()

        self.writeLog(u'启动发布者模式(如需修改通讯地址请重启程序)')

    #----------------------------------------------------------------------
    def startSubscriber(self, reqAddress, subAddress, copyRatio):
        """"""
        self.mode = self.MODE_SUBSCRIBER
        self.copyRatio = copyRatio

        if not self.client:
            self.client = TcClient(self, reqAddress, subAddress)
            self.client.usePickle()
            self.client.subscribeTopic('')
            self.client.start()

        self.writeLog(u'启动订阅者模式,运行时请不要执行其他交易操作')
        self.initTarget()

    #----------------------------------------------------------------------
    def stop(self):
        """"""
        if self.client:
            self.client.stop()
            self.writeLog(u'订阅者模式已停止')

        if self.server:
            self.server.stop()
            self.writeLog(u'发布者模式已停止')

        self.mode = None

    #----------------------------------------------------------------------
    def registerEvent(self):
        """"""
        self.eventEngine.register(EVENT_POSITION, self.processPositionEvent)
        self.eventEngine.register(EVENT_TRADE, self.processTradeEvent)
        self.eventEngine.register(EVENT_TIMER, self.processTimerEvent)
        self.eventEngine.register(EVENT_ORDER, self.processOrderEvent)

    #----------------------------------------------------------------------
    def checkAndTrade(self, vtSymbol):
        """"""
        if self.checkNoWorkingOrder(vtSymbol):
            self.newOrder(vtSymbol)
        else:
            self.cancelOrder(vtSymbol)

    #----------------------------------------------------------------------
    def processTimerEvent(self, event):
        """"""
        if self.mode != self.MODE_PROVIDER:
            return

        self.count += 1
        if self.count < self.interval:
            return
        self.count = 0

        for vtPositionName in self.posDict.keys():
            self.publishPos(vtPositionName)

    #----------------------------------------------------------------------
    def processTradeEvent(self, event):
        """"""
        trade = event.dict_['data']

        vtPositionName = '.'.join([trade.vtSymbol, trade.direction])

        if trade.offset == OFFSET_OPEN:
            self.posDict[vtPositionName] += trade.volume
        else:
            self.posDict[vtPositionName] -= trade.volume

        if self.mode == self.MODE_PROVIDER:
            self.publishPos(vtPositionName)

    #----------------------------------------------------------------------
    def processPositionEvent(self, event):
        """"""
        position = event.dict_['data']
        self.posDict[position.vtPositionName] = position.position

    #----------------------------------------------------------------------
    def processOrderEvent(self, event):
        """"""
        order = event.dict_['data']
        if order.status == STATUS_REJECTED:
            self.writeLog(u'监控到委托拒单,停止运行')
            self.stop()

    #----------------------------------------------------------------------
    def publishPos(self, vtPositionName):
        """"""
        l = vtPositionName.split('.')
        direction = l[-1]
        vtSymbol = vtPositionName.replace('.' + direction, '')

        data = {
            'vtSymbol': vtSymbol,
            'vtPositionName': vtPositionName,
            'pos': self.posDict[vtPositionName]
        }
        self.server.publish('', data)

    #----------------------------------------------------------------------
    def updatePos(self, data):
        """"""
        vtSymbol = data['vtSymbol']
        if vtSymbol not in self.subscribeSet:
            contract = self.mainEngine.getContract(vtSymbol)

            req = VtSubscribeReq()
            req.symbol = contract.symbol
            req.exchange = contract.exchange
            self.mainEngine.subscribe(req, contract.gatewayName)

        vtPositionName = data['vtPositionName']
        target = int(data['pos'] * self.copyRatio)
        self.targetDict[vtPositionName] = target

        self.checkAndTrade(vtSymbol)

    #----------------------------------------------------------------------
    def newOrder(self, vtSymbol):
        """"""
        for vtPositionName in self.targetDict.keys():
            if vtSymbol not in vtPositionName:
                continue

            pos = self.posDict[vtPositionName]
            target = self.targetDict[vtPositionName]
            if pos == target:
                continue

            contract = self.mainEngine.getContract(vtSymbol)
            tick = self.mainEngine.getTick(vtSymbol)
            if not tick:
                return

            req = VtOrderReq()
            req.symbol = contract.symbol
            req.exchange = contract.exchange
            req.priceType = PRICETYPE_LIMITPRICE
            req.volume = abs(target - pos)

            # Open position
            if target > pos:
                req.offset = OFFSET_OPEN

                if DIRECTION_LONG in vtPositionName:
                    req.direction = DIRECTION_LONG
                    if tick.upperLimit:
                        req.price = tick.upperLimit
                    else:
                        req.price = tick.askPrice1
                elif DIRECTION_SHORT in vtPositionName:
                    req.direction = DIRECTION_SHORT
                    if tick.lowerLimit:
                        req.price = tick.lowerLimit
                    else:
                        req.price = tick.bidPrice1

                self.mainEngine.sendOrder(req, contract.gatewayName)

            # Close position
            elif target < pos:
                req.offset = OFFSET_CLOSE

                if DIRECTION_LONG in vtPositionName:
                    req.direction = DIRECTION_SHORT
                    if tick.upperLimit:
                        req.price = tick.upperLimit
                    else:
                        req.price = tick.askPrice1

                elif DIRECTION_SHORT in vtPositionName:
                    req.direction = DIRECTION_LONG
                    if tick.lowerLimit:
                        req.price = tick.lowerLimit
                    else:
                        req.price = tick.bidPrice1

                # Use auto-convert for solving today/yesterday position problem
                reqList = self.mainEngine.convertOrderReq(req)
                for convertedReq in reqList:
                    self.mainEngine.sendOrder(convertedReq,
                                              contract.gatewayName)

            # Write log
            msg = u'发出%s委托 %s%s %s@%s' % (vtSymbol, req.direction, req.offset,
                                          req.price, req.volume)
            self.writeLog(msg)

    #----------------------------------------------------------------------
    def cancelOrder(self, vtSymbol):
        """
        Cancel all orders of a certain vtSymbol
        """
        l = self.mainEngine.getAllWorkingOrders()
        for order in l:
            if order.vtSymbol == vtSymbol:
                req = VtCancelOrderReq()
                req.orderID = order.orderID
                req.frontID = order.frontID
                req.sessionID = order.sessionID
                req.symbol = order.symbol
                req.exchange = order.exchange
                self.mainEngine.cancelOrder(req, order.gatewayName)

        self.writeLog(u'撤销%s全部活动中委托' % vtSymbol)

    #----------------------------------------------------------------------
    def checkNoWorkingOrder(self, vtSymbol):
        """
        Check if there is still any working orders of a certain vtSymbol
        """
        l = self.mainEngine.getAllWorkingOrders()
        for order in l:
            if order.vtSymbol == vtSymbol:
                return False

        return True

    #----------------------------------------------------------------------
    def writeLog(self, msg):
        """"""
        log = VtLogData()
        log.logContent = msg

        event = Event(EVENT_TC_LOG)
        event.dict_['data'] = log
        self.eventEngine.put(event)

    #----------------------------------------------------------------------
    def getPos(self):
        """
        Get currenct position data of provider
        """
        return dict(self.posDict)

    #----------------------------------------------------------------------
    def initTarget(self):
        """
        Init target data of subscriber based on position data from provider
        """
        d = self.client.getPos()
        for vtPositionName, pos in d.items():
            l = vtPositionName.split('.')
            direction = l[-1]
            vtSymbol = vtPositionName.replace('.' + direction, '')

            data = {
                'vtPositionName': vtPositionName,
                'vtSymbol': vtSymbol,
                'pos': pos
            }
            self.updatePos(data)

        self.writeLog(u'目标仓位初始化完成')
Exemple #6
0
class RsEngine(object):
    """RPC服务引擎"""

    settingFileName = 'RS_setting.json'
    settingFilePath = getJsonPath(settingFileName, __file__)

    name = 'RPC服务'

    #----------------------------------------------------------------------
    def __init__(self, mainEngine, eventEngine):
        """Constructor"""
        self.mainEngine = mainEngine
        self.eventEngine = eventEngine

        self.server = None  # RPC服务对象
        self.repAddress = EMPTY_STRING  # REP地址
        self.pubAddress = EMPTY_STRING  # PUB地址

        self.functionDict = {}  # 调用过的函数对象缓存字典

        self.loadSetting()
        self.registerEvent()

    #----------------------------------------------------------------------
    def loadSetting(self):
        """读取配置"""
        with open(self.settingFilePath) as f:
            d = json.load(f)

            self.repAddress = d['repAddress']
            self.pubAddress = d['pubAddress']

            self.server = RpcServer(self.repAddress, self.pubAddress)
            self.server.usePickle()
            self.server.register(self.call)
            self.server.start()

    #----------------------------------------------------------------------
    def registerEvent(self):
        """注册事件监听"""
        self.eventEngine.registerGeneralHandler(self.processEvent)

    #----------------------------------------------------------------------
    def call(self, d):
        """调用函数"""
        nameList = d['nameList']  # 对象属性列表
        nameTuple = tuple(nameList)  # 转化为元组
        args = d['args']  # 调用参数
        kwargs = d['kwargs']

        # 如果已经有缓存,则直接调用
        if nameTuple in self.functionDict:
            function = self.functionDict[nameTuple]
            result = function(*args, **kwargs)
            return result
        # 逐层寻找函数对象
        else:
            # 根对象为主引擎
            obj = self.mainEngine

            # 逐层寻找对象属性
            for name in nameTuple:
                obj = obj.__getattribute__(name)

            # 缓存结果
            self.functionDict[nameTuple] = obj

            # 调用最终对象
            result = obj(*args, **kwargs)
            return result

    #----------------------------------------------------------------------
    def processEvent(self, event):
        """处理事件推送"""
        self.server.publish(b'', event)

    #----------------------------------------------------------------------
    def stop(self):
        """停止"""
        self.server.stop()
Exemple #7
0
class TcEngine(object):
    """交易复制引擎"""
    MODE_PROVIDER = 1
    MODE_SUBSCRIBER = 2
    
    #----------------------------------------------------------------------
    def __init__(self, mainEngine, eventEngine):
        """Constructor"""
        self.mainEngine = mainEngine
        self.eventEngine = eventEngine
        
        self.mode = None                    # Subscriber/Provider
        self.posDict = defaultdict(int)     # vtPositionName:int
        self.targetDict = defaultdict(int)  # vtPositionName:int
        self.copyRatio = 1
        self.interval = 1
        self.subscribeSet = set()
        
        self.count = 0
        self.server = None                  # RPC Server
        self.client = None                  # RPC Client
        
        self.registerEvent()
    
    #----------------------------------------------------------------------
    def startProvider(self, repAddress, pubAddress, interval):
        """"""
        self.mode = self.MODE_PROVIDER
        self.interval = interval
        
        if not self.server:
            self.server = RpcServer(repAddress, pubAddress)
            self.server.usePickle()
            self.server.register(self.getPos)
            self.server.start()
        
        self.writeLog(u'启动发布者模式(如需修改通讯地址请重启程序)')
    
    #----------------------------------------------------------------------
    def startSubscriber(self, reqAddress, subAddress, copyRatio):
        """"""
        self.mode = self.MODE_SUBSCRIBER
        self.copyRatio = copyRatio
        
        if not self.client:
            self.client = TcClient(self, reqAddress, subAddress)
            self.client.usePickle()
            self.client.subscribeTopic('')
            self.client.start()
        
        self.writeLog(u'启动订阅者模式,运行时请不要执行其他交易操作')        
        self.initTarget()
    
    #----------------------------------------------------------------------
    def stop(self):
        """"""
        if self.client:
            self.client.stop()
            self.writeLog(u'订阅者模式已停止')
        
        if self.server:
            self.server.stop()
            self.writeLog(u'发布者模式已停止')
        
        self.mode = None
        
    #----------------------------------------------------------------------
    def registerEvent(self):
        """"""
        self.eventEngine.register(EVENT_POSITION, self.processPositionEvent)
        self.eventEngine.register(EVENT_TRADE, self.processTradeEvent)
        self.eventEngine.register(EVENT_TIMER, self.processTimerEvent)
        self.eventEngine.register(EVENT_ORDER, self.processOrderEvent)
    
    #----------------------------------------------------------------------
    def checkAndTrade(self, vtSymbol):
        """"""
        if self.checkNoWorkingOrder(vtSymbol):
            self.newOrder(vtSymbol)
        else:
            self.cancelOrder(vtSymbol)        
    
    #----------------------------------------------------------------------
    def processTimerEvent(self, event):
        """"""
        if self.mode != self.MODE_PROVIDER:
            return
            
        self.count += 1
        if self.count < self.interval:
            return
        self.count = 0
        
        for vtPositionName in self.posDict.keys():
            self.publishPos(vtPositionName)
        
    #----------------------------------------------------------------------
    def processTradeEvent(self, event):
        """"""
        trade = event.dict_['data']
        
        vtPositionName = '.'.join([trade.vtSymbol, trade.direction])
        
        if trade.offset == OFFSET_OPEN:
            self.posDict[vtPositionName] += trade.volume
        else:
            self.posDict[vtPositionName] -= trade.volume
        
        if self.mode == self.MODE_PROVIDER:
            self.publishPos(vtPositionName)
    
    #----------------------------------------------------------------------
    def processPositionEvent(self, event):
        """"""
        position = event.dict_['data']
        self.posDict[position.vtPositionName] = position.position        
    
    #----------------------------------------------------------------------
    def processOrderEvent(self, event):
        """"""
        order = event.dict_['data']
        if order.status == STATUS_REJECTED:
            self.writeLog(u'监控到委托拒单,停止运行')
            self.stop()
    
    #----------------------------------------------------------------------
    def publishPos(self, vtPositionName):
        """"""
        l = vtPositionName.split('.')
        direction = l[-1]
        vtSymbol = vtPositionName.replace('.' + direction, '')        
        
        data = {
            'vtSymbol': vtSymbol,
            'vtPositionName': vtPositionName,
            'pos': self.posDict[vtPositionName]
        }
        self.server.publish('', data)
    
    #----------------------------------------------------------------------
    def updatePos(self, data):
        """"""
        vtSymbol = data['vtSymbol']
        if vtSymbol not in self.subscribeSet:
            contract = self.mainEngine.getContract(vtSymbol)
            
            req = VtSubscribeReq()
            req.symbol = contract.symbol
            req.exchange = contract.exchange
            self.mainEngine.subscribe(req, contract.gatewayName)
        
        vtPositionName = data['vtPositionName']
        target = int(data['pos'] * self.copyRatio)
        self.targetDict[vtPositionName] = target
        
        self.checkAndTrade(vtSymbol)
    
    #----------------------------------------------------------------------
    def newOrder(self, vtSymbol):
        """"""
        for vtPositionName in self.targetDict.keys():
            if vtSymbol not in vtPositionName:
                continue
            
            pos = self.posDict[vtPositionName]
            target = self.targetDict[vtPositionName]            
            if pos == target:
                continue
            
            contract = self.mainEngine.getContract(vtSymbol)
            tick = self.mainEngine.getTick(vtSymbol)
            if not tick:
                return
            
            req = VtOrderReq()
            req.symbol = contract.symbol
            req.exchange = contract.exchange
            req.priceType = PRICETYPE_LIMITPRICE            
            req.volume = abs(target - pos)
            
            # Open position
            if target > pos:
                req.offset = OFFSET_OPEN
                
                if DIRECTION_LONG in vtPositionName:
                    req.direction = DIRECTION_LONG
                    if tick.upperLimit:
                        req.price = tick.upperLimit
                    else:
                        req.price = tick.askPrice1
                elif DIRECTION_SHORT in vtPositionName:
                    req.direction = DIRECTION_SHORT
                    if tick.lowerLimit:
                        req.price = tick.lowerLimit
                    else:
                        req.price = tick.bidPrice1
                
                self.mainEngine.sendOrder(req, contract.gatewayName)
            
            # Close position
            elif target < pos:
                req.offset = OFFSET_CLOSE
                
                if DIRECTION_LONG in vtPositionName:
                    req.direction = DIRECTION_SHORT
                    if tick.upperLimit:
                        req.price = tick.upperLimit
                    else:
                        req.price = tick.askPrice1
                
                elif DIRECTION_SHORT in vtPositionName:
                    req.direction = DIRECTION_LONG
                    if tick.lowerLimit:
                        req.price = tick.lowerLimit
                    else:
                        req.price = tick.bidPrice1
                    
                # Use auto-convert for solving today/yesterday position problem
                reqList = self.mainEngine.convertOrderReq(req)
                for convertedReq in reqList:
                    self.mainEngine.sendOrder(convertedReq, contract.gatewayName)
            
            # Write log
            msg = u'发出%s委托 %s%s %s@%s' %(vtSymbol, req.direction, req.offset,
                                            req.price, req.volume)
            self.writeLog(msg)

    #----------------------------------------------------------------------
    def cancelOrder(self, vtSymbol):
        """
        Cancel all orders of a certain vtSymbol
        """
        l = self.mainEngine.getAllWorkingOrders()
        for order in l:
            if order.vtSymbol == vtSymbol:
                req = VtCancelOrderReq()
                req.orderID = order.orderID
                req.frontID = order.frontID
                req.sessionID = order.sessionID
                req.symbol = order.symbol
                req.exchange = order.exchange
                self.mainEngine.cancelOrder(req, order.gatewayName)
        
        self.writeLog(u'撤销%s全部活动中委托' %vtSymbol)
    
    #----------------------------------------------------------------------
    def checkNoWorkingOrder(self, vtSymbol):
        """
        Check if there is still any working orders of a certain vtSymbol
        """
        l = self.mainEngine.getAllWorkingOrders()
        for order in l:
            if order.vtSymbol == vtSymbol:
                return False
        
        return True

    #----------------------------------------------------------------------
    def writeLog(self, msg):
        """"""
        log = VtLogData()
        log.logContent = msg
        
        event = Event(EVENT_TC_LOG)
        event.dict_['data'] = log
        self.eventEngine.put(event)
    
    #----------------------------------------------------------------------
    def getPos(self):
        """
        Get currenct position data of provider
        """
        return dict(self.posDict)
    
    #----------------------------------------------------------------------
    def initTarget(self):
        """
        Init target data of subscriber based on position data from provider
        """
        d = self.client.getPos()
        for vtPositionName, pos in d.items():
            l = vtPositionName.split('.')
            direction = l[-1]
            vtSymbol = vtPositionName.replace('.' + direction, '')
            
            data = {
                'vtPositionName': vtPositionName,
                'vtSymbol': vtSymbol,
                'pos': pos
            }
            self.updatePos(data)
        
        self.writeLog(u'目标仓位初始化完成')
Exemple #8
0
class RsEngine(object):
    """RPC服务引擎"""
    
    settingFileName = 'RS_setting.json'
    settingFilePath = getJsonPath(settingFileName, __file__)    
    
    name = u'RPC服务'

    #----------------------------------------------------------------------
    def __init__(self, mainEngine, eventEngine):
        """Constructor"""
        self.mainEngine = mainEngine
        self.eventEngine = eventEngine
        
        self.server = None                  # RPC服务对象
        self.repAddress = EMPTY_STRING      # REP地址
        self.pubAddress = EMPTY_STRING      # PUB地址
        
        self.functionDict = {}              # 调用过的函数对象缓存字典
        
        self.loadSetting()
        self.registerEvent()
        
    #----------------------------------------------------------------------
    def loadSetting(self):
        """读取配置"""
        with open(self.settingFilePath) as f:
            d = json.load(f)
            
            self.repAddress = d['repAddress']
            self.pubAddress = d['pubAddress']
            
            self.server = RpcServer(self.repAddress, self.pubAddress)
            self.server.usePickle()
            self.server.register(self.call)
            self.server.start()
            
    #----------------------------------------------------------------------
    def registerEvent(self):
        """注册事件监听"""
        self.eventEngine.registerGeneralHandler(self.processEvent)
        
    #----------------------------------------------------------------------
    def call(self, d):
        """调用函数"""
        nameList = d['nameList']        # 对象属性列表
        nameTuple = tuple(nameList)     # 转化为元组
        args = d['args']                # 调用参数
        kwargs = d['kwargs']
        
        # 如果已经有缓存,则直接调用
        if nameTuple in self.functionDict:
            function = self.functionDict[nameTuple]
            result = function(*args, **kwargs)
            return result
        # 逐层寻找函数对象
        else:
            # 根对象为主引擎
            obj = self.mainEngine
            
            # 逐层寻找对象属性
            for name in nameTuple:
                obj = obj.__getattribute__(name)
            
            # 缓存结果
            self.functionDict[nameTuple] = obj
            
            # 调用最终对象
            result = obj(*args, **kwargs)
            return result
        
    #----------------------------------------------------------------------
    def processEvent(self, event):
        """处理事件推送"""
        self.server.publish('', event)
    
    #----------------------------------------------------------------------
    def stop(self):
        """停止"""
        self.server.stop()