Example #1
0
    def __init__(self):
        # Open connections: wsh --> Client
        self.clients = {}

        # Delegate server logic to a separate class
        self.manager = GSManager(self)

        # Check for lagged-out clients
        tornado.ioloop.PeriodicCallback(self.check_lastpings, 60).start()
Example #2
0
    def __init__(self):
        # Open connections: wsh --> Client
        self.clients = {}

        # Delegate server logic to a separate class
        self.manager = GSManager(self)

        # Check for lagged-out clients
        tornado.ioloop.PeriodicCallback(self.check_lastpings, 60).start()
Example #3
0
class GSInterface():
    _instance = None

    @staticmethod
    @synchronized(lock)
    def instance():
        if not GSInterface._instance:
            GSInterface._instance = GSInterface()
        return GSInterface._instance

    def __init__(self):
        # Open connections: wsh --> Client
        self.clients = {}

        # Delegate server logic to a separate class
        self.manager = GSManager(self)

        # Check for lagged-out clients
        tornado.ioloop.PeriodicCallback(self.check_lastpings, 60).start()

    ##################################################
    # Handle connection, disconnection, and timeouts #
    ##################################################

    @synchronized(lock)
    def do_disconnect(self, conn):
        if conn is not None:
            logging.info('Performing disconnection: %s ' % id(conn))
            if conn in self.clients:
                client = self.clients.pop(conn)
                self.manager.remClient(client)
            try:
                conn.close()
            except:
                pass

    @synchronized(lock)
    def handle_disconnect(self, conn):
        """ Remove and notify manager.  Ignore if called previously. """
        logging.info('Handling disconnection: %s ' % id(conn))
        if conn in self.clients:
            client = self.clients.pop(conn)
            self.manager.remClient(client)

    @synchronized(lock)
    def check_lastpings(self):
        to_close = set()
        for conn in self.clients:
            if self.clients[conn].timed_out():
                to_close.add(conn)

        for conn in to_close:
            logging.info('Client timed out.  Closing WS: %s' % id(conn))
            self.do_disconnect(conn)

    #########################################
    # Messages between client and GSManager #
    #########################################

    @synchronized(lock)
    def sendToClient(self, client, msgtype, **kwargs):

        # Create message object
        msg = {'msgtype': msgtype, 'message': {}}
        for k in kwargs:
            msg['message'][k] = kwargs[k]

        # Log and send message
        logging.debug('Sending message to %s:' % id(client.conn))
        logging.debug(msg)
        msgJSON = GSEncoder().encode(msg)
        client.conn.write_message(msgJSON)

    @synchronized(lock)
    def sendToAllClients(self, msgtype, **kwargs):
        for k in self.clients:
            self.sendToClient(self.clients[k], msgtype, **kwargs)

    def respondToClient(self, client, querytype, queryid, **kwargs):
        self.sendToClient(client, 'RESPONSE', querytype=querytype,
                          queryid=queryid, **kwargs)

    @synchronized(lock)
    def receiveFromClient(self, conn, msg):
        """ Handle client info and pings internally.  Pass all other
            client messages to GSManager. """

        # Receive client info directly
        if msg['msgtype'] == 'CLIENT_INFO':
            info = msg['message']
            client = Client(conn, info['playerName'], info['playerId'], info['gsversion'])
            self.clients[conn] = client
            self.manager.addClient(client)
            self.respondToClient(client, 'CLIENT_INFO', msg['msgid'])
            db_manager.record_login(info['playerId'], info['gsversion'])

        else:
            # Verify that we have client info 
            if conn in self.clients:
                client = self.clients[conn]
            else:
                logging.error("""Received message from WS Connection with no
                              registered client. Conn ID: %s""" % id(conn))
                logging.error(msg)
    
            # Handle pings directly
            if msg['msgtype'] == 'PING':
                logging.debug('Received ping from %s' % client)
                client.update_lastping()
                logging.debug('Sending pingback to %s' % client)
                self.respondToClient(client, 'PING', msg['msgid'])
    
            # Pass other messages to manager
            else:
                logging.info('Received message from client: %s ' % client)
                logging.info(msg)
                self.manager.receiveFromClient(client, msg['msgtype'],
                                               msg['msgid'], msg['message'])
Example #4
0
class GSInterface():
    _instance = None

    @staticmethod
    @synchronized(lock)
    def instance():
        if not GSInterface._instance:
            GSInterface._instance = GSInterface()
        return GSInterface._instance

    def __init__(self):
        # Open connections: wsh --> Client
        self.clients = {}

        # Delegate server logic to a separate class
        self.manager = GSManager(self)

        # Check for lagged-out clients
        tornado.ioloop.PeriodicCallback(self.check_lastpings, 60).start()

    ##################################################
    # Handle connection, disconnection, and timeouts #
    ##################################################

    @synchronized(lock)
    def do_disconnect(self, conn):
        if conn is not None:
            logging.info('Performing disconnection: %s ' % id(conn))
            if conn in self.clients:
                client = self.clients.pop(conn)
                self.manager.remClient(client)
            try:
                conn.close()
            except:
                pass

    @synchronized(lock)
    def handle_disconnect(self, conn):
        """ Remove and notify manager.  Ignore if called previously. """
        logging.info('Handling disconnection: %s ' % id(conn))
        if conn in self.clients:
            client = self.clients.pop(conn)
            self.manager.remClient(client)

    @synchronized(lock)
    def check_lastpings(self):
        to_close = set()
        for conn in self.clients:
            if self.clients[conn].timed_out():
                to_close.add(conn)

        for conn in to_close:
            logging.info('Client timed out.  Closing WS: %s' % id(conn))
            self.do_disconnect(conn)

    #########################################
    # Messages between client and GSManager #
    #########################################

    @synchronized(lock)
    def sendToClient(self, client, msgtype, **kwargs):

        # Create message object
        msg = {'msgtype': msgtype, 'message': {}}
        for k in kwargs:
            msg['message'][k] = kwargs[k]

        # Log and send message
        logging.debug('Sending message to %s:' % id(client.conn))
        logging.debug(msg)
        msgJSON = GSEncoder().encode(msg)
        client.conn.write_message(msgJSON)

    @synchronized(lock)
    def sendToAllClients(self, msgtype, **kwargs):
        for k in self.clients:
            self.sendToClient(self.clients[k], msgtype, **kwargs)

    def respondToClient(self, client, querytype, queryid, **kwargs):
        self.sendToClient(client, 'RESPONSE', querytype=querytype,
                          queryid=queryid, **kwargs)

    @synchronized(lock)
    def receiveFromClient(self, conn, msg):
        """ Handle client info and pings internally.  Pass all other
            client messages to GSManager. """

        # Receive client info directly
        if msg['msgtype'] == 'CLIENT_INFO':
            info = msg['message']
            client = Client(conn, info['playerName'], info['playerId'], info['gsversion'])
            self.clients[conn] = client
            self.manager.addClient(client)
            self.respondToClient(client, 'CLIENT_INFO', msg['msgid'])
            db_manager.record_login(info['playerId'], info['gsversion'])

        else:
            # Verify that we have client info 
            if conn in self.clients and self.clients[conn] is not None:
                client = self.clients[conn]
            else:
                logging.error("""Received message from WS Connection with no
                              registered client. Conn ID: %s""" % id(conn))
                logging.error(msg)

            # Any message verifes that you're still connected
            client.update_lastping()
    
            # Handle pings directly
            if msg['msgtype'] == 'PING':
                logging.debug('Received ping from %s' % client)
                logging.debug('Sending pingback to %s' % client)
                self.respondToClient(client, 'PING', msg['msgid'])
    
            # Pass other messages to manager
            else:
                logging.info('Received message from client: %s ' % client)
                logging.info(msg)
                self.manager.receiveFromClient(client, msg['msgtype'],
                                               msg['msgid'], msg['message'])