Пример #1
0
class SVShandler:
    def __init__(self):
        self.qm = QueueManager(address=('/tmp/SVSqueue'), authkey='gnarf')
        self.qm.start()
        self.queue = self.qm.get_queue()

        self.proc = multiprocessing.Process( \
            target=SVService.processWorker, \
            args=[])
        self.proc.start()

    def __del__(self):
        if self.proc.is_alive():
            self.send('bye', 'System shutdown', None)
        self.proc.join()
        self.qm.shutdown()

    def addClient(self, queuepath):
        self.send('addClient', 'new Connection', queuepath)

    def removeClient(self, queue):
        self.send('removeClient', 'Peer lost', queue)

    def send(self, msgtag, text, obj=None):
        self.queue.put((msgtag, text, obj))

    def getQueue(self):
        return self.queue

    def cycle(self):
        if self.proc.is_alive(): return True
        else:
            self.proc.join()
            self.qm.shutdown()
            return False
Пример #2
0
    def addClient(self, conn):
        queuepath = '/tmp/SVCqueue' + str(self.generateQueueNumber())

        m = QueueManager(address=(queuepath), authkey='gnarf')
        m.start()
        queue = m.get_queue()

        proc = multiprocessing.Process( \
            target=SVClient.processWorker, \
                args=(queuepath,conn,))
        proc.start()
        
        self.connections[conn] = (m, queuepath, queue, proc)
Пример #3
0
class SVService:
    def __init__(self):
        inQueueManager = QueueManager(address=('/tmp/SVSqueue'), \
            authkey='gnarf')
        inQueueManager.connect()
        self.inQueue = inQueueManager.get_queue()

        self.handleMsg = msgHandler(self.logfunc)
        self.handleMsg.register('init', self.do_init)
        self.handleMsg.register('addClient', self.do_addClient)
        self.handleMsg.register('peerQuit', self.do_peerQuit)
        self.handleMsg.register('exit', self.do_exit)
        self.handleMsg.register('procDead', self.do_procDead)
        self.handleMsg.register('chatLobby', self.do_chatLobby)
        self.handleMsg.register('nameProposed', self.do_nameProposed)
        self.handleMsg.register('PINGsent', self.do_PINGsent)
        self.handleMsg.register('PINGreceived', self.do_PINGreceived)
        self.handleMsg.register('PONGreceived', self.do_PONGreceived)
        self.handleMsg.register('getUserList', self.do_getUserList)
        self.handleMsg.register('chatPrivate', self.do_chatPrivate, 3, False)
        self.handleMsg.register('shutdown', self.do_shutdown)
        self.handleMsg.register('syslog', self.do_syslog, 3, False)

        self.clients = {}
        self.lastClient = 0

        self.SVG = SVGhandler()

        self.init = False
        self.keep_alive = True

    def __del__(self):
        del self.inQueue
        del self.handleMsg
        del self.clients
        #if self.MDproc.is_alive():
            #self.sendClient(self.MDqueuepath, 'bye', 'system shutdown')
        self.MDproc.join()
        self.mqm.shutdown()

    def cycle(self):
        msg = self.inQueue.get() # blocking get
        self.performInQueueMsg(msg)

        if msg[0] == 'bye':
            print 'SVService: Bye'
            return False

        return self.keep_alive

    def sendClient(self, ID, msgtag, text, obj=None):
        msg = (msgtag, text, obj)
        self.clients[ID]['queue'].put((msgtag, text, obj))

    def getSenderInfo(self, ID):
        return {'name': self.clients[ID]['name'],
                'ID': ID}

    def removeClient(self, clientID, msg):
        clientName = self.clients[clientID]['name']
        del self.clients[clientID]['name']
        del self.clients[clientID]['queue']
        del self.clients[clientID]['state']
        del self.clients[clientID]

        for ID in self.clients.keys():
            if not self.clients[ID]['name'][0] == '_':
                self.sendClient(ID, 'userLeft', msg, clientID)

    def performInQueueMsg(self, msg):
        if not self.handleMsg.performMsg(msg):
            print '[SVService] unknown cmd: ' + msg[0]

    def logfunc(self, msg):
        self.sendClient(self.MDqueuepath, 'syslog', 'event from SVService', str(msg))

    def do_init(self, param):
        if not self.init:
            self.MDqueuepath = '/tmp/MDqueue'
            self.mqm = QueueManager(address=(self.MDqueuepath), \
                authkey='gnarf')
            self.mqm.start()
            self.MDqueue = self.mqm.get_queue()

            self.clients[self.MDqueuepath] = { \
                'name': 'Majordomo',
                'queue': self.MDqueue,
                'state': 'master'}

            self.MDproc = multiprocessing.Process( \
                target=Majordomo.processWorker,
                args=[])
            self.MDproc.start()

            self.init = True

    def do_addClient(self, param):
        self.lastClient += 1
        queuepath = param[2] # we use path to named pipe as client id

        m = QueueManager(address=(queuepath), authkey='gnarf')
        m.connect()
        queue = m.get_queue()

        self.clients[queuepath] = { \
            'name': '_SVuser' + str(self.lastClient),
            'queue': queue,
            'state': 'init'}

    def do_peerQuit(self, param):
        clientID = param[2]
        if clientID in self.clients:
            self.removeClient(clientID, 'peer disconnected')
        
    def do_exit(self, param):
        clientID = param[2]
        if clientID in self.clients:
            self.removeClient(clientID, 'user left us')

    def do_procDead(self, param):
        clientID = param[2]
        if clientID in self.clients:
            self.removeClient(clientID, \
                'process dead - this should never happen')

    def do_chatLobby(self, param):
        text = param[1]
        senderID = param[2]

        for ID in self.clients.keys():
            self.sendClient(ID, 'lobbyMsg', text, \
                self.getSenderInfo(senderID))

    def do_nameProposed(self, param):
        proposedName = param[1]
        clientID = param[2]

        if proposedName in [x['name'] for x in self.clients.values()]:
            self.sendClient(clientID, 'clientNameDenied', \
                'a user with this name is already online')

        elif len(proposedName) > 15:
            self.sendClient(clientID, 'clientNameDenied', \
                'name too long')

        elif len(proposedName) < 3:
            self.sendClient(clientID, 'clientNameDenied', \
                'name too short')

        elif proposedName[0] == '_':
            self.sendClient(clientID, 'clientNameDenied', \
                'name must not begin with an underscore')

        elif  ':' in proposedName or ' ' in proposedName:
            self.sendClient(clientID, 'clientNameDenied', \
                'name must not contain : or space')

        else: 
            self.clients[clientID]['name'] = proposedName
            self.sendClient(clientID, 'clientNameAccepted', \
                proposedName)
            for sink in self.clients.keys():
                if not self.clients[sink]['name'][0] == '_':
                    self.sendClient(sink, 'userJoined', 'user joined', \
                        self.getSenderInfo(clientID))

    def do_PINGsent(self, param): pass

    def do_PINGreceived(self, param):
        clientID = param[2]
        self.sendClient(clientID, 'sendPONG', 'send PONG to peer')

    def do_PONGreceived(self, param): pass

    def do_getUserList(self, param):
        clientID = param[2]
        userList = [self.getSenderInfo(x) \
            for x in self.clients.keys() 
            if (not self.clients[x]['name'][0] == '_') or
            (clientID == self.MDqueuepath)]
        self.sendClient(clientID, 'userList', '', userList)

    def do_chatPrivate(self, param):
        msg = param[1]
        sourceID, sinkID = param[2]

        self.sendClient(sinkID, 'privateMsg', msg, \
            self.getSenderInfo(sourceID))

    def do_shutdown(self, param):
        self.sendClient(self.MDqueuepath, 'bye', 'system shutdown')

        self.keep_alive = False

    def do_syslog(self, param):
        msgtag, msg, userID = param
        self.sendClient(self.MDqueuepath, 'syslog', 'event from ' + userID, msg)