Example #1
0
class ClientHandler(socketserver.BaseRequestHandler):
    """
    This is the ClientHandler class. Everytime a new client connects to the
    server, a new ClientHandler object will be created. This class represents
    only connected clients, and not the server itself. If you want to write
    logic for the server, you must write it outside this class
    """
    def handle(self):
        """
        This method handles the connection between a client and the server.
        """
        self.ip = self.client_address[0]
        self.port = self.client_address[1]
        self.connection = self.request

        # Init
        self.messageEncoder = MessageEncoder()
        self.messageParser = MessageParser()

        # Loop that listens for messages from the client
        while True:
            received_string = self.connection.recv(4096).decode()

            if received_string == "":
                self.connection.close()
                del connected_clients[self.connection]
                break
            else:
                payload = self.messageParser.parse(received_string)
                if 'login' in payload.keys():
                    if re.match("^[A-Za-z0-9_-]*$", payload['login']):
                        self.connection.send(
                            self.messageEncoder.encode_history(
                                history).encode())
                        connected_clients[self.connection] = payload['login']
                    else:
                        self.connection.send(
                            self.messageEncoder.encode_error(
                                "Invalid username").encode())
                elif 'logout' in payload.keys():
                    self.connection.close()
                    del connected_clients[self.connection]
                    return
                elif 'message' in payload.keys():
                    message = self.messageEncoder.encode_message(
                        connected_clients[self.connection], payload['message'])
                    history.append(message)
                    for conn in connected_clients.keys():
                        conn.send(message.encode())
                elif 'names' in payload.keys():
                    self.connection.send(
                        self.messageEncoder.encode_info(', '.join(
                            connected_clients.values())).encode())
                elif 'help' in payload.keys():
                    self.connection.send(
                        self.messageEncoder.encode_info(
                            "This is the help").encode())
Example #2
0
    def handle(self):
        """
        This method handles the connection between a client and the server.
        """
        self.ip = self.client_address[0]
        self.port = self.client_address[1]
        self.connection = self.request

        # Init
        self.messageEncoder = MessageEncoder()
        self.messageParser = MessageParser()

        # Loop that listens for messages from the client
        while True:
            received_string = self.connection.recv(4096).decode()

            if received_string == "":
                self.connection.close()
                del connected_clients[self.connection]
                break
            else:
                payload = self.messageParser.parse(received_string)
                if 'login' in payload.keys():
                    if re.match("^[A-Za-z0-9_-]*$", payload['login']):
                        self.connection.send(
                            self.messageEncoder.encode_history(
                                history).encode())
                        connected_clients[self.connection] = payload['login']
                    else:
                        self.connection.send(
                            self.messageEncoder.encode_error(
                                "Invalid username").encode())
                elif 'logout' in payload.keys():
                    self.connection.close()
                    del connected_clients[self.connection]
                    return
                elif 'message' in payload.keys():
                    message = self.messageEncoder.encode_message(
                        connected_clients[self.connection], payload['message'])
                    history.append(message)
                    for conn in connected_clients.keys():
                        conn.send(message.encode())
                elif 'names' in payload.keys():
                    self.connection.send(
                        self.messageEncoder.encode_info(', '.join(
                            connected_clients.values())).encode())
                elif 'help' in payload.keys():
                    self.connection.send(
                        self.messageEncoder.encode_info(
                            "This is the help").encode())
Example #3
0
    def __init__(self, aCritter):
        """Initializes the post office.

        Arguments:
            aCritter: The critter.

        """
        self.mCritter = aCritter

        settings = self.mCritter.getSettings()

        # Configuring the logger.
        self.mLogger = logging.getLogger(self.__class__.__name__)
        self.mLogger.propagate = False
        # TODO: Remove the hardcoded value of the path.
        handler = logging.FileHandler('/tmp/' + self.mCritter.mCrittnick + '.log')
        # TODO: Remove the hardcoded value of the formatter.
        formatter = logging.Formatter('[%(asctime)s][%(threadName)28s][%(levelname)8s] - %(message)s')
        handler.setFormatter(formatter)
        self.mLogger.addHandler(handler)
        self.mLogger.setLevel(self.mCritter.mSettings.get('logging', 'level'))

        policy = settings.get('crittwork', 'policy')

        addressPublisher = addressSubscriber = ''

        # TODO: Now this is an ifology, it should be a real policy.
        if policy == 'multicast':
            addressPublisher = addressSubscriber = settings.get('crittwork', 'multicast')
        elif policy == 'broker':
            addressPublisher  = settings.get('crittwork', 'brokerPublisher')
            addressSubscriber = settings.get('crittwork', 'brokerSubscriber')
        else:
            assert False, "Invalid crittwork policy selected."

        # TODO: Get from the factory.
        self.mTransport = TransportZMQ(addressPublisher, addressSubscriber)

        self.mOutgoingAnnouncementsQueue = Queue()
        self.mIncomingAnnouncementsQueue = Queue()

        self.mRiteConnector = RiteConnector(aCritter.mRites)

        self.mMessageEncoder = MessageEncoder()

        # Spawning the announcement publisher.
        self.mLogger.debug("Spawning the announcement publisher.")
        self.mAnnouncementPublisher = AnnouncementPublisher(self)
        self.mAnnouncementPublisher.setDaemon(True)

        # Spawning the announcement subscriber.
        self.mLogger.debug("Spawning the announcement subscriber.")
        self.mAnnouncementSubscriber = AnnouncementSubscriber(self)
        self.mAnnouncementSubscriber.setDaemon(True)

        # Spawning the message router.
        # FIXME: Jealous.
        self.mLogger.debug("Spawning the message router.")
        self.mMessageRouter = MessageRouter(self)
        self.mMessageRouter.setDaemon(True)
Example #4
0
    def __init__(self, host, server_port):
        """
        This method is run when creating a new Client object
        """

        # Set up the socket connection to the server
        self.connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # Init
        self.host = host
        self.server_port = server_port
        self.state = State.LOGIN;

        self.messageEncoder = MessageEncoder()
        self.messageParser = MessageParser()

        self.username = ""

        # Run client
        self.run()
Example #5
0
class Client:
    """
    This is the chat client class
    """

    def __init__(self, host, server_port):
        """
        This method is run when creating a new Client object
        """

        # Set up the socket connection to the server
        self.connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # Init
        self.host = host
        self.server_port = server_port
        self.state = State.LOGIN;

        self.messageEncoder = MessageEncoder()
        self.messageParser = MessageParser()

        self.username = ""

        # Run client
        self.run()

    def run(self):
        try:
            # Initiate the connection to the server
            self.connection.connect((self.host, self.server_port))
            messageReceiver = MessageReceiver(self, self.connection)
            messageReceiver.start()
        except socket.error as e:
            sys.exit("Connection to server refused.")

        while (not self.connection._closed):
            if self.state == State.LOGIN:
                print("Username:"******"Disconnected from server")



    def disconnect(self):
        self.connection.close()

    def receive_payload(self, payload):
        message = self.messageParser.parse(payload)
        if 'error' in message.keys():
            print("Error:", message['error'])
            self.state = State.LOGIN
        elif 'info' in message.keys():
            print("Info:", message['info'])
        elif 'message' in message.keys():
            if self.state == State.CHATROOM:
            	if message['sender'] != self.username:
                	print(message['sender']+":", message['message'])
        elif 'history' in message.keys():
            print("")
            print("Welcome", self.username, "to CHATROOM!")
            for msg in message['history']:
            	if msg['sender'] == self.username:
            		print(msg['message'])
            	else:
                	print(msg['sender']+":", msg['message'])
            self.state = State.CHATROOM

    def send_payload(self, payload):
    	if not self.connection._closed:
        	self.connection.send(payload.encode())
Example #6
0
class PostOffice(object):
    """The PostOffice that handles all the communication.

    Attributes:
        mCritter:                    The critter.
        mIncomingAnnouncementsQueue: The queue of incoming announcements.
        mLogger:                     The logger.
        mMessageEncoder:             The message encoder.
        mOutgoingAnnouncementsQueue: The queue of outgoing announcements.
        mAnnouncementPublisher:      The announcement publisher.
        mAnnouncementSubscriber:     The announcement subscriber.
        mMessageRouter:              The message router.
        mRiteConnector:              The rite connector.
        mTransport:                  The transport.

    """

    def __init__(self, aCritter):
        """Initializes the post office.

        Arguments:
            aCritter: The critter.

        """
        self.mCritter = aCritter

        settings = self.mCritter.getSettings()

        # Configuring the logger.
        self.mLogger = logging.getLogger(self.__class__.__name__)
        self.mLogger.propagate = False
        # TODO: Remove the hardcoded value of the path.
        handler = logging.FileHandler('/tmp/' + self.mCritter.mCrittnick + '.log')
        # TODO: Remove the hardcoded value of the formatter.
        formatter = logging.Formatter('[%(asctime)s][%(threadName)28s][%(levelname)8s] - %(message)s')
        handler.setFormatter(formatter)
        self.mLogger.addHandler(handler)
        self.mLogger.setLevel(self.mCritter.mSettings.get('logging', 'level'))

        policy = settings.get('crittwork', 'policy')

        addressPublisher = addressSubscriber = ''

        # TODO: Now this is an ifology, it should be a real policy.
        if policy == 'multicast':
            addressPublisher = addressSubscriber = settings.get('crittwork', 'multicast')
        elif policy == 'broker':
            addressPublisher  = settings.get('crittwork', 'brokerPublisher')
            addressSubscriber = settings.get('crittwork', 'brokerSubscriber')
        else:
            assert False, "Invalid crittwork policy selected."

        # TODO: Get from the factory.
        self.mTransport = TransportZMQ(addressPublisher, addressSubscriber)

        self.mOutgoingAnnouncementsQueue = Queue()
        self.mIncomingAnnouncementsQueue = Queue()

        self.mRiteConnector = RiteConnector(aCritter.mRites)

        self.mMessageEncoder = MessageEncoder()

        # Spawning the announcement publisher.
        self.mLogger.debug("Spawning the announcement publisher.")
        self.mAnnouncementPublisher = AnnouncementPublisher(self)
        self.mAnnouncementPublisher.setDaemon(True)

        # Spawning the announcement subscriber.
        self.mLogger.debug("Spawning the announcement subscriber.")
        self.mAnnouncementSubscriber = AnnouncementSubscriber(self)
        self.mAnnouncementSubscriber.setDaemon(True)

        # Spawning the message router.
        # FIXME: Jealous.
        self.mLogger.debug("Spawning the message router.")
        self.mMessageRouter = MessageRouter(self)
        self.mMessageRouter.setDaemon(True)

    def start(self):
        """Starts the post office by starting its threads."""
        self.mAnnouncementPublisher.start()
        self.mAnnouncementSubscriber.start()
        self.mMessageRouter.start()

    def encode(self, aData):
        """A facade method to hide message encoder from clients.

        Arguments:
            aData: The dictionary of parameters.

        Returns:
            A message.

        """
        return self.mMessageEncoder.encode(aData)

    def putIntoAnEnvelope(self, aMessage):
        return self.mMessageEncoder.putIntoAnEnvelope(aMessage)

    def putIncomingAnnouncement(self, aMessage):
        """Puts an incoming announcement (in the form of a message) into the queue.

        Arguments:
            aMessage The message to be processed.

        """
        self.mIncomingAnnouncementsQueue.put(aMessage)

    def putOutgoingAnnouncement(self, aMessage):
        """Puts an outgoing announcement (in the form of a message) into the queue.

        Arguments:
            aMessage The message to be sent.

        """
        self.mOutgoingAnnouncementsQueue.put(aMessage)

    def getIncomingAnnouncement(self):
        """Gets an incoming announcement (in the form of a message) from the queue.

        Returns The message to be processed.

        """
        return self.mIncomingAnnouncementsQueue.get()

    def getOutgoingAnnouncement(self):
        """Gets an outgoing announcement (in the form of a message) from the queue.

        Returns The message to be sent.

        """
        return self.mOutgoingAnnouncementsQueue.get()

    def putCommand(self, aRite, aCommand, aPriority=PRIORITY_DEFAULT):
        self.mRiteConnector.putCommand(aRite, aCommand, aPriority)

    def putMessage(self, aRite, aMessage, aPriority=PRIORITY_DEFAULT):
        self.mRiteConnector.putMessage(aRite, aMessage, aPriority)

    def addSubscriptionChannel(self, aSubscriptionChannel):
        self.mTransport.addSubscriptionChannel(aSubscriptionChannel)

    def removeSubscriptionChannel(self, aSubscriptionChannel):
        self.mTransport.removeSubscriptionChannel(aSubscriptionChannel)

    def getCorrespondingSubscriptionChannel(self, aMessage):
        return SUBSCRIPTION_CHANNEL_ALL