def __init__(self, stageaddress, midiportindex):
        Subscriber.__init__(self)
        self.setThreading(True)

        self.publisher = LivePublisher()
        self.midiRouter = Showtime_Live.MidiRouter.MidiRouter(midiportindex)

        if not self.midiRouter.midiActive():
            print("--- No midi loopback port available, incoming messages to Ableton will be considerably slower")
            print("--- Is loopMidi running?\n")

        if not stageaddress:
            print("Creating internal stage at tcp://127.0.0.1:6000")
            self.stageNode = ZstNode("ShowtimeStage")
            port = 6000
            address = "tcp://*:" + str(port)
            self.stageNode.reply.socket.bind(address)
            self.stageNode.start()
            stageaddress = "127.0.0.1:" + str(port)

        # Create showtime node
        self.node = ZstNode("LiveNode", stageaddress)
        self.node.start()
        self.node.request_register_node()
        self.register_methods()
        self.subscribeMatch('[^' + PyroPrefixes.DELIMITER + ']*')
        self.registrar = RegistrationThread(self.node)
        self.registrar.daemon = True
        self.registrar.start()
class LiveRouter(Subscriber):
    def __init__(self, stageaddress, midiportindex):
        Subscriber.__init__(self)
        self.setThreading(True)

        self.publisher = LivePublisher()
        self.midiRouter = Showtime_Live.MidiRouter.MidiRouter(midiportindex)

        if not self.midiRouter.midiActive():
            print("--- No midi loopback port available, incoming messages to Ableton will be considerably slower")
            print("--- Is loopMidi running?\n")

        if not stageaddress:
            print("Creating internal stage at tcp://127.0.0.1:6000")
            self.stageNode = ZstNode("ShowtimeStage")
            port = 6000
            address = "tcp://*:" + str(port)
            self.stageNode.reply.socket.bind(address)
            self.stageNode.start()
            stageaddress = "127.0.0.1:" + str(port)

        # Create showtime node
        self.node = ZstNode("LiveNode", stageaddress)
        self.node.start()
        self.node.request_register_node()
        self.register_methods()
        self.subscribeMatch('[^' + PyroPrefixes.DELIMITER + ']*')
        self.registrar = RegistrationThread(self.node)
        self.registrar.daemon = True
        self.registrar.start()

    def close(self):
        self.registrar.stop()
        self.node.close()
        if(hasattr(self, "stageNode")):
            self.stageNode.close()
        self.getDaemon().shutdown(True)
        self.midiRouter.close()

    def register_methods(self):
        if(self.midiRouter.midiActive()):
            self.node.request_register_method(
                "play_note",
                ZstMethod.WRITE,
                {
                    "trackindex": None,
                    "note": None,
                    "state": None,
                    "velocity": None
                },
                self.midiRouter.play_midi_note)

    def event(self, event):
        methodName = event.subject[2:]
        pyroType = event.subject[:1]

        if pyroType == PyroPrefixes.REGISTRATION:
            self.registrar.add_registration_request(methodName, event.msg["methodaccess"], event.msg["args"], self.incoming)
        elif pyroType == PyroPrefixes.OUTGOING or pyroType == PyroPrefixes.RESPONDER:
            print "Live-->ST: " + str(event.subject) + '=' + str(event.msg)
            if methodName in self.node.methods:
                self.node.update_local_method_by_name(methodName, event.msg)
            else:
                print "Outgoing method not registered!"

    def incoming(self, message):
        print "ST-->Live: " + str(message.name)
        args = message.args if message.args else {}
        self.publisher.send_to_live(message.name, args)