Exemple #1
0
def manage(socketio_handler):
    socketIO = SocketIO('http://localhost:5000', Namespace=MasterNamespace)
    #socketIO = SocketIO('https://autobotcloud.com', Namespace=MasterNamespace)
    namespace = socketIO.get_namespace()
    socketIO.on('connect', connected)
    socketIO.on('disconnect', disconnected)
    namespace.master = Master()
    socketio_handler.ws = socketIO  #trial code to hand over this instance of socketio to logging
    socketIO.emit('ready')
    logger.info("emitted ready")
    socketIO.emit('getbots')
    logger.info("emitted get bots")
    socketIO.wait()
class Transaction(object):
    def __init__(self):
        self.custom_timers = {}
        self.word_list = buildArray( )
        self.word_list_length = len(self.word_list)
        self.socketIO = SocketIO(HOST, PORT)
        self.socketIO.define(Namespace)
                    
    def makeCall( self, jsonObject ):
        
        start_timer = time.time()

        self.socketIO.message(jsonObject)
        self.socketIO.wait(0.01)
        namespace = self.socketIO.get_namespace()
        #print namespace.response
    
        latency = time.time() - start_timer
    
        self.custom_timers['trie_service_sockets'] = latency
    
        #if latency > 5:
            #writeErrorInfo('latency value of %f with %s' %(latency, url) )
        #if r.status_code != 200:
            #writeErrorInfo('status code with %s is %s' %(r.status_code, url) )
    
        #assert (r.status_code == 200), 'Bad HTTP Response'
        #assert ('suggestions' in namespace.response), 'No suggestions'
    
    def run(self):
        
        #get a random word from the word_list and call to typeahead
        whichPhrase = random.randrange(0,self.word_list_length)
        phrase = self.word_list[whichPhrase]
        word = phrase.split(" ")[0]
        #print 'word is %s' % word
        message = ""
        jsonObject = ""
        #loop through the chars in the word skipping the first
        #for char in word:
        #    message = message + char
        #    jsonObject = {'@class': 'com.glg.service.TrieObject', 'entity':'cm', 'prefix':message}
        #    self.makeCall( jsonObject )
        
        jsonObject = {'@class': 'com.glg.service.TrieObject', 'entity':'cm', 'prefix':word}
        self.makeCall( jsonObject )
Exemple #3
0
class SocketClient_Listener(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

        self.socket = SocketIO('http://houston123.edu.vn',
                               5000,
                               wait_for_connection=False)

    def run(self):
        try:

            _BaseNamespace = self.socket.get_namespace()
            submit_ssid = self.socket.define(BaseNamespace, '/submit_ssid')

            def handle_kick(self):
                logging.debug("DMM")
                global Check_Register
                Check_Register = True
                Thread_Tag_Register = Register_MFRC522_Thread()
                Thread_Tag_Register.start()

            def on_connect():
                logging.debug("Connected")
                submit_ssid.emit('submit_sid', {'devID': 1, 'Descrip': "DIA"})

            def on_reconnect():
                logging.debug('Reconnect')
                submit_ssid.emit('submit_sid', {'devID': 1, 'Descrip': "DIA"})

            self.socket.on('connect', on_connect())
            _BaseNamespace.on('reconnect', on_reconnect)
            submit_ssid.on('Register_Signal', handle_kick)

            self.socket.wait()
        except Exception as e:
            raise e
Exemple #4
0
class WaptSocketIOClient(threading.Thread):
    def __init__(self,config_filename = 'c:/wapt/wapt-get.ini',task_manager=None):
        threading.Thread.__init__(self)
        self.name = 'SocketIOClient'
        self.config_filename = config_filename
        self.task_manager = task_manager
        self.config = WaptServiceConfig(config_filename)
        self.socketio_client = None
        self.wapt_remote_calls = None


    def run(self):
        self.config.reload_if_updated()
        with Wapt(config_filename = self.config.config_filename) as tmp_wapt:
            logger.info('Starting socketio on "%s://%s:%s" ...' % (self.config.websockets_proto,self.config.websockets_host,self.config.websockets_port))
            logger.debug('Certificate checking : %s' %  self.config.websockets_verify_cert)
            while True:
                try:
                    connect_params = dict(
                        uuid = tmp_wapt.host_uuid,
                    )
                    host_key = tmp_wapt.get_host_key()
                    host_cert = tmp_wapt.get_host_certificate()

                    if not self.socketio_client and self.config.websockets_host:
                        logger.debug('Creating socketio client')
                        logger.debug('Proxies : %s'%self.config.waptserver.proxies)
                        # bug in socketio... ? we must not pass proxies at all (even None) if we don"t want to switch to polling mode...
                        kwargs = {}
                        if self.config.waptserver.proxies and self.config.waptserver.proxies.get(self.config.websockets_proto,None) is not None:
                            kwargs['proxies'] = self.config.waptserver.proxies


                        signed_connect_params = host_key.sign_claim(connect_params,signer_certificate_chain = host_cert)

                        self.socketio_client = SocketIO(
                                host="%s://%s" % (self.config.websockets_proto,self.config.websockets_host),
                                port=self.config.websockets_port,
                                Namespace = WaptSocketIORemoteCalls,
                                resource=self.config.websockets_root,
                                verify=self.config.websockets_verify_cert,
                                wait_for_connection = False,
                                transport = ['websocket'],
                                ping_interval = self.config.websockets_ping,
                                hurry_interval_in_seconds = self.config.websockets_hurry_interval,
                                params = {'uuid': tmp_wapt.host_uuid, 'login':jsondump(signed_connect_params)},
                                **kwargs)
                        self.socketio_client.get_namespace().wapt = tmp_wapt
                        self.socketio_client.get_namespace().task_manager = self.task_manager

                    if self.socketio_client and self.config.websockets_host:
                        if not self.socketio_client.connected:
                            signed_connect_params = host_key.sign_claim(connect_params,signer_certificate_chain = host_cert)

                            self.socketio_client._http_session.params.update({'uuid': tmp_wapt.host_uuid,'login':jsondump(signed_connect_params)})
                            self.socketio_client.define(WaptSocketIORemoteCalls)
                            self.socketio_client.get_namespace().wapt = tmp_wapt
                            self.socketio_client.get_namespace().task_manager = self.task_manager
                            self.socketio_client.connect('')
                        else:
                            self.socketio_client.emit('wapt_pong')

                        if self.socketio_client.connected:
                            logger.info('Socket IO listening for %ss' % self.config.websockets_check_config_interval )
                            startwait = time.time()
                            self.socketio_client.wait(self.config.websockets_check_config_interval)
                            # QAD workaround for cases where server disconnect but client is between 2 states.
                            # In this case; wait() immediately returns, leading to an indefinite loop eating 1 core.
                            if time.time() - startwait < self.config.websockets_check_config_interval-2:
                                raise Exception('Websocket client seems disconnected. Force Websocket connection to be recreated')
                    elif not self.config.websockets_host:
                        self.socketio_client = None
                        time.sleep(self.config.websockets_retry_delay)
                    else:
                        time.sleep(self.config.websockets_retry_delay)

                    if self.config.reload_if_updated():
                        if self.socketio_client:
                            self.socketio_client.disconnect()
                        raise EWaptException('Configuration changed, force Websocket connection to be recreated')


                except Exception as e:
                    try:
                        logger.info('Error in socket io connection %s' % repr(e))
                        self.config.reload_if_updated()
                        if self.socketio_client:
                            logger.debug('stop sio client')
                            self.socketio_client = None
                    finally:
                        logger.debug('Socket IO Stopped, waiting %ss before retrying' %
                            self.config.websockets_retry_delay)
                        time.sleep(self.config.websockets_retry_delay)
Exemple #5
0
class threadNetworker(QtCore.QObject):
    """socketIO network handler."""
    def __init__(self, ip, port):
        super().__init__()
        self.ip = ip
        self.port = port

    """Signals to trigger internal methods of threadNetworker."""
    init_connect = pyqtSignal()
    disconnect = pyqtSignal()
    get_task = pyqtSignal(dict)
    send_results = pyqtSignal(Task)
    submit_task = pyqtSignal(dict)
    """Signals to trigger events in the main Qt thread."""
    conn_status = pyqtSignal(int)  # 1 for success, -1 for error.
    task_received = pyqtSignal(str, int)  # job_id, iter_no.
    error_received = pyqtSignal(int, str)
    result_sent = pyqtSignal(str, int)  # job_id, iter_no.

    @pyqtSlot()
    def socket_initconnect(self):
        """Connects to socketIO server and emits conn_status()."""
        try:
            self.sio = SocketIO(self.ip,
                                self.port,
                                roctoClass,
                                wait_for_connection=False)
            self.conn_status.emit(1)
        except exceptions.ConnectionError:
            self.conn_status.emit(-1)

    @pyqtSlot()
    def socket_disconnect(self):
        self.sio.disconnect()
        self.conn_status.emit(0)

    @pyqtSlot(dict)
    def socket_gettask(self, info):
        """Gets task from the socketIO server."""
        # Change according to api/worker.json.
        try:
            # TODO: logging
            self.sio.emit('request_task', info)
            self.sio.wait(.1)
            # Process self.sio.get_namespace().task_queue[0]['version'] here.
            job_id = self.sio.get_namespace().task_queue[0]['jobId']
            iter_no = self.sio.get_namespace().task_queue[0]['iterNo']
            self.task_received.emit(job_id, iter_no)

        except ServerErr as e:
            # TODO: logging
            self.error_received.emit(e.err, e.message)

    @pyqtSlot(Task)
    def socket_sendresults(self, Task):
        """Sends the passed Task to the server."""
        # TODO:ERROR_CATCH

        self.result_sent.emit(Task.job_id, Task.iter_no)
        if self.sio.connected == True:
            self.sio.emit(
                'send_results',
                {
                    'version':
                    API_VERSION,
                    'jobId':
                    str(Task.job_id),
                    'iterNo':
                    Task.iter_no,
                    'exitStatus':
                    Task.status,
                    'content':
                    str(Task.output)[2:-1]
                    if Task.proc_ret.returncode == 0 else Task.
                    proc  # removes b'' # content may change according to exit status
                })
        else:
            self.sio = SocketIO(self.ip,
                                self.port,
                                roctoClass,
                                wait_for_connection=False)
            self.sio.emit(
                'send_results',
                {
                    'version': API_VERSION,
                    'jobId': str(Task.job_id),
                    'iterNo': Task.iter_no,
                    'exitStatus': Task.status,
                    'content': str(Task.output)
                    [2:
                     -1]  # removes b'' # content may change according to exit status
                })

    @pyqtSlot(dict)
    def socket_submitjob(self, submission):
        # Error prone. What if no connection?
        print(submission.keys())
        self.sio.emit('submit_job', submission)
Exemple #6
0
class WaptSocketIOClient(threading.Thread):
    def __init__(self,config_filename = 'c:/wapt/wapt-get.ini',task_manager=None,request_timeout=None):
        threading.Thread.__init__(self)
        self.name = 'SocketIOClient'
        self.config_filename = config_filename
        self.task_manager = task_manager
        self.config = WaptServiceConfig(config_filename)
        self.socketio_client = None
        self.wapt_remote_calls = None
        self.server_authorization_token = None
        if request_timeout is None:
            request_timeout = self.config.websockets_request_timeout
        self.request_timeout = request_timeout

    def run(self):
        self.config.reload_if_updated()
        with Wapt(config_filename = self.config.config_filename) as tmp_wapt:
            logger.info('Starting socketio on "%s://%s:%s" ...' % (self.config.websockets_proto,self.config.websockets_host,self.config.websockets_port))
            logger.debug('Certificate checking : %s' %  self.config.websockets_verify_cert)

            def get_connect_params(wapt):
                connect_params = {'uuid': wapt.host_uuid}
                if not self.server_authorization_token:
                    try:
                        self.server_authorization_token = wapt.get_auth_token('websocket')
                        logger.info('Websocket token: %s' % self.server_authorization_token)
                        connect_params['token'] = self.server_authorization_token
                    except Exception as e:
                        logger.warning('Websocket connect params: %s' % e)
                        self.server_authorization_token = None
                return {'params':connect_params,
                        'cert'  :(wapt.get_host_certificate_filename(),wapt.get_host_key_filename())}
            while True:
                try:
                    connect_params = get_connect_params(tmp_wapt)
                    if not self.socketio_client and self.config.websockets_host:
                        logger.debug('Creating socketio client')
                        logger.debug('Proxies : %s'%self.config.waptserver.proxies)
                        # bug in socketio... ? we must not pass proxies at all (even None) if we don"t want to switch to polling mode...
                        kwargs = {}
                        if self.config.waptserver.proxies and self.config.waptserver.proxies.get(self.config.websockets_proto,None) is not None:
                            kwargs['proxies'] = self.config.waptserver.proxies

                        kwargs.update(connect_params)
                        self.socketio_client = SocketIO(
                                host="%s://%s" % (self.config.websockets_proto,self.config.websockets_host),
                                port=self.config.websockets_port,
                                Namespace = WaptSocketIORemoteCalls,
                                resource=self.config.websockets_root,
                                verify=self.config.websockets_verify_cert,
                                wait_for_connection = False,
                                transport = ['websocket'],
                                ping_interval = self.config.websockets_ping,
                                hurry_interval_in_seconds = self.config.websockets_hurry_interval,
                                request_timeout = self.request_timeout,
                                **kwargs)
                        self.socketio_client.get_namespace().wapt = tmp_wapt
                        self.socketio_client.get_namespace().task_manager = self.task_manager

                    if self.socketio_client and self.config.websockets_host:
                        if not self.socketio_client.connected:
                            self.socketio_client._http_session.update(connect_params)
                            self.socketio_client.define(WaptSocketIORemoteCalls)
                            self.socketio_client.get_namespace().wapt = tmp_wapt
                            self.socketio_client.get_namespace().task_manager = self.task_manager
                            self.socketio_client.connect('')
                        else:
                            # be sure server DB is aware of the current connection.
                            # could be avoided
                            self.socketio_client.emit('wapt_pong')

                        if self.socketio_client.connected:
                            logger.info('Socket IO listening for %ss' % self.config.websockets_check_config_interval )
                            startwait = time.time()
                            self.socketio_client.wait(self.config.websockets_check_config_interval)
                            # QAD workaround for cases where server disconnect but client is between 2 states.
                            # In this case; wait() immediately returns, leading to an indefinite loop eating 1 core.
                            if time.time() - startwait < self.config.websockets_check_config_interval-2:
                                raise Exception('Websocket client seems disconnected. Force Websocket connection to be recreated')

                    elif not self.config.websockets_host:
                        self.socketio_client = None
                        time.sleep(self.config.websockets_retry_delay)
                    else:
                        time.sleep(self.config.websockets_retry_delay)

                    if self.config.reload_if_updated():
                        tmp_wapt.reload_config_if_updated()
                        if self.socketio_client:
                            self.socketio_client.disconnect()
                        raise EWaptException('Configuration changed, force Websocket connection to be recreated')


                except Exception as e:
                    try:
                        # reset token
                        self.server_authorization_token = None
                        self.config.reload_if_updated()
                        if self.socketio_client:
                            self.socketio_client = None
                    finally:
                        logger.info(u'Exception %s, Socket IO Stopped, waiting %ss before retrying' %
                            (repr(e),self.config.websockets_retry_delay))
                        time.sleep(self.config.websockets_retry_delay)
Exemple #7
0
class LetschatClient():
    """
    The LetschatClient makes API Calls to the Lets-chat Web API via websocket

    It also manages some of the Client state for Rooms that the associated token (User or Bot)
    is associated with.

    Init:
        :Args:
            hostname (str): lets-chat host.
            port (int): lets-chat using port.
            token (str): Your lets-chat Authentication token.
    """

    class LetschatNamespace(BaseNamespace):
        """
        Define socket.io client behavier for lets-chat
        """

        def __init__(self, io, path):
            super().__init__(io, path)
            self._user = None
            self._connected = False
            self._rooms = []
            self._joined_rooms = []

        def on_connect(self, *args):
            self._io.on('rooms:new', self.on_rooms_new_message)
            self._io.on('rooms:archive', self.on_rooms_archive_message)
            self._io.emit('account:whoami', self.on_account_whoami_response)

        def on_account_whoami_response(self, *args):
            self._user = dict(args[0])
            self._io.emit('rooms:list', self.on_rooms_list_response)

        def on_rooms_list_response(self, *args):
            self._rooms.clear()

            for room in args[0]:
                self._rooms.append(dict(room))

            if not self._connected:
                log.info('Connected')
                self._connected = True

        def on_rooms_join_response(self, *args):
            room = args[0]
            if room.get('id') in [room_.get('id') for room_ in self._rooms]:
                log.info('Joined {}'.format(room.get('name')))
                self._joined_rooms.append(room.get('id'))

        def on_rooms_create_response(self, *args):
            room = dict(args[0])
            self._rooms.append(room)

        def on_rooms_new_message(self, *args):
            room = dict(args[0])
            if not room.get('id') in [room_.get('id') for room_ in self._rooms]:
                log.info('Created {}'.format(room.get('name')))
                self._rooms.append(room)

        def on_rooms_archive_message(self, *args):
            room = [room for room in self._rooms if room.get('id') == args[0].get('id')]
            if room:
                room = room[0]
                log.info('Archived {}'.format(room.get('name')))
                self._rooms.remove(room)

        def on_rooms_update_message(self, *args):
            room = [room for room in self._rooms if room.get('id') == args[0].get('id')]
            if room:
                room = room[0]
                log.info('Updated {}'.format(room.get('name')))
                room['name'] = args[0].get('name')
                room['description'] = args[0].get('description')

        @property
        def username(self):
            return self._user.get('username')

        @property
        def rooms(self):
            return self._rooms

        @property
        def joined_rooms(self):
            joined_ = [room for room in self._rooms if room.get('id') in self._joined_rooms]
            return joined_

        @property
        def connected(self):
            return self._connected

    def __init__(self, hostname, port, token, protocol='http', callbacks={}):
        self._sio = SocketIO('{}://{}'.format(protocol, hostname), port,
                             LetschatClient.LetschatNamespace,
                             params={'token': token})
        self.on_users_join_handler = callbacks.get('on_users_join', None)
        self.on_users_leave_handler = callbacks.get('on_users_leave', None)
        self.on_messages_new_handler = callbacks.get('on_messages_new', None)

        # wait for connection sequence.
        while not self._sio.get_namespace().connected:
            self._sio.wait(seconds=1)

    def emit(self, event, *args, **kw):
        self._sio.emit(event, *args, **kw)

    def wait(self, seconds=None):
        self._sio.wait(seconds)

    def emit_messages_create(self, message):
        self.emit('messages:create', message)

    def emit_rooms_join(self, roomid):
        self.emit('rooms:join', roomid, self.server.on_rooms_join_response)

    def emit_rooms_leave(self, roomid):
        self.emit('rooms:leave', roomid)
        self.server._joined_rooms.remove(roomid)

    def emit_rooms_create(self, name):
        options = {
            'name': name,
            'slug': name,
        }
        self.emit('rooms:create', options, self.server.on_rooms_create_response)

    def emit_rooms_archive(self, roomid):
        room = [room for room in self.server._rooms if room.get('id') == roomid]
        if room:
            options = {
                'id': roomid,
            }
            self.emit('rooms:archive', options)

    def emit_rooms_update(self, roomid, name=None, desc=None):
        room = [room for room in self.server._rooms if room.get('id') == roomid]
        if room:
            options = dict(room[0])
            if name is not None:
                options['name'] = name
            if description is not None:
                options['description'] = desc
            self.emit('rooms:update', options)

    def emit_rooms_users(self, roomid):
        users = []
        def on_rooms_users_response(event, *args):
            for user in args[0]:
                users.append(dict(user))
            event.set()

        event_ = threading.Event()
        callback = functools.partial(on_rooms_users_response, event_)
        options = {
            'room': roomid,
        }
        self.emit('rooms:users', options, callback)
        event_.wait()

        return users

    def emit_users_list(self):
        users = []
        def on_users_list_response(event, *args):
            for user in args[0]:
                users.append(dict(user))
            event.set()

        event_ = threading.Event()
        callback = functools.partial(on_users_list_response, event_)
        self.emit('users:list', callback)
        event_.wait()

        return users

    @property
    def on_users_join_handler(self):
        return self._on_users_join_handler

    @on_users_join_handler.setter
    def on_users_join_handler(self, handler):
        self._on_users_join_handler = handler
        self._sio.on('users:join', self.on_users_join_handler)
        return True

    @property
    def on_users_leave_handler(self):
        return self._on_users_leave_handler

    @on_users_leave_handler.setter
    def on_users_leave_handler(self, handler):
        self._on_users_leave_handler = handler
        self._sio.on('users:leave', self.on_users_leave_handler)
        return True

    @property
    def on_messages_new_handler(self):
        return self._on_messages_new_handler

    @on_messages_new_handler.setter
    def on_messages_new_handler(self, handler):
        self._on_messages_new_handler = handler
        self._sio.on('messages:new', self._on_messages_new_handler)
        return True

    @property
    def server(self):
        return self._sio.get_namespace()
Exemple #8
0
class TestSocketIO(TestCase):

    def setUp(self):
        self.socketIO = SocketIO(HOST, PORT)
        self.called_on_response = False

    def tearDown(self):
        del self.socketIO

    def on_response(self, *args):
        self.called_on_response = True
        for arg in args:
            if isinstance(arg, dict):
                self.assertEqual(arg, PAYLOAD)
            else:
                self.assertEqual(arg, DATA)

    def is_connected(self, socketIO, connected):
        childThreads = [
            socketIO._rhythmicThread,
            socketIO._listenerThread,
        ]
        for childThread in childThreads:
            self.assertEqual(not connected, childThread.done.is_set())
        self.assertEqual(connected, socketIO.connected)

    def test_disconnect(self):
        'Terminate child threads after disconnect'
        self.is_connected(self.socketIO, True)
        self.socketIO.disconnect()
        self.is_connected(self.socketIO, False)
        # Use context manager
        with SocketIO(HOST, PORT) as self.socketIO:
            self.is_connected(self.socketIO, True)
        self.is_connected(self.socketIO, False)

    def test_message(self):
        'Message'
        self.socketIO.define(Namespace)
        self.socketIO.message()
        self.socketIO.wait(0.1)
        namespace = self.socketIO.get_namespace()
        self.assertEqual(namespace.response, 'message_response')

    def test_message_with_data(self):
        'Message with data'
        self.socketIO.define(Namespace)
        self.socketIO.message(DATA)
        self.socketIO.wait(0.1)
        namespace = self.socketIO.get_namespace()
        self.assertEqual(namespace.response, DATA)

    def test_message_with_payload(self):
        'Message with payload'
        self.socketIO.define(Namespace)
        self.socketIO.message(PAYLOAD)
        self.socketIO.wait(0.1)
        namespace = self.socketIO.get_namespace()
        self.assertEqual(namespace.response, PAYLOAD)

    def test_message_with_callback(self):
        'Message with callback'
        self.socketIO.message(callback=self.on_response)
        self.socketIO.wait_for_callbacks(seconds=0.1)
        self.assertEqual(self.called_on_response, True)

    def test_message_with_callback_with_data(self):
        'Message with callback with data'
        self.socketIO.message(DATA, self.on_response)
        self.socketIO.wait_for_callbacks(seconds=0.1)
        self.assertEqual(self.called_on_response, True)

    def test_emit(self):
        'Emit'
        self.socketIO.define(Namespace)
        self.socketIO.emit('emit')
        self.socketIO.wait(0.1)
        self.assertEqual(self.socketIO.get_namespace().argsByEvent, {
            'emit_response': (),
        })

    def test_emit_with_payload(self):
        'Emit with payload'
        self.socketIO.define(Namespace)
        self.socketIO.emit('emit_with_payload', PAYLOAD)
        self.socketIO.wait(0.1)
        self.assertEqual(self.socketIO.get_namespace().argsByEvent, {
            'emit_with_payload_response': (PAYLOAD,),
        })

    def test_emit_with_multiple_payloads(self):
        'Emit with multiple payloads'
        self.socketIO.define(Namespace)
        self.socketIO.emit('emit_with_multiple_payloads', PAYLOAD, PAYLOAD)
        self.socketIO.wait(0.1)
        self.assertEqual(self.socketIO.get_namespace().argsByEvent, {
            'emit_with_multiple_payloads_response': (PAYLOAD, PAYLOAD),
        })

    def test_emit_with_callback(self):
        'Emit with callback'
        self.socketIO.emit('emit_with_callback', self.on_response)
        self.socketIO.wait_for_callbacks(seconds=0.1)
        self.assertEqual(self.called_on_response, True)

    def test_emit_with_callback_with_payload(self):
        'Emit with callback with payload'
        self.socketIO.emit('emit_with_callback_with_payload',
                           self.on_response)
        self.socketIO.wait_for_callbacks(seconds=0.1)
        self.assertEqual(self.called_on_response, True)

    def test_emit_with_callback_with_multiple_payloads(self):
        'Emit with callback with multiple payloads'
        self.socketIO.emit('emit_with_callback_with_multiple_payloads',
                           self.on_response)
        self.socketIO.wait_for_callbacks(seconds=0.1)
        self.assertEqual(self.called_on_response, True)

    def test_emit_with_event(self):
        'Emit to trigger an event'
        self.socketIO.on('emit_with_event_response', self.on_response)
        self.socketIO.emit('emit_with_event', PAYLOAD)
        self.socketIO.wait_for_callbacks(0.1)
        self.assertEqual(self.called_on_response, True)

    def test_ack(self):
        'Trigger server callback'
        self.socketIO.define(Namespace)
        self.socketIO.emit('ack', PAYLOAD)
        self.socketIO.wait(0.1)
        self.assertEqual(self.socketIO.get_namespace().argsByEvent, {
            'ack_response': (PAYLOAD,),
            'ack_callback_response': (PAYLOAD,),
        })

    def test_namespaces(self):
        'Behave differently in different namespaces'
        mainNamespace = self.socketIO.define(Namespace)
        chatNamespace = self.socketIO.define(Namespace, '/chat')
        newsNamespace = self.socketIO.define(Namespace, '/news')
        newsNamespace.emit('emit_with_payload', PAYLOAD)
        self.socketIO.wait(0.1)
        self.assertEqual(mainNamespace.argsByEvent, {})
        self.assertEqual(chatNamespace.argsByEvent, {})
        self.assertEqual(newsNamespace.argsByEvent, {
            'emit_with_payload_response': (PAYLOAD,),
        })
class WaptSocketIOClient(threading.Thread):
    def __init__(self,config_filename = 'c:/wapt/wapt-get.ini',task_manager=None):
        threading.Thread.__init__(self)
        self.name = 'SocketIOClient'
        self.config_filename = config_filename
        self.task_manager = task_manager
        self.config = WaptServiceConfig(config_filename)
        self.socketio_client = None
        self.wapt_remote_calls = None
        self.server_authorization_token = None


    def run(self):
        self.config.reload_if_updated()
        with Wapt(config_filename = self.config.config_filename) as tmp_wapt:
            logger.info('Starting socketio on "%s://%s:%s" ...' % (self.config.websockets_proto,self.config.websockets_host,self.config.websockets_port))
            logger.debug('Certificate checking : %s' %  self.config.websockets_verify_cert)

            def get_connect_params(wapt):
                connect_params = {'uuid': wapt.host_uuid}
                if not self.server_authorization_token:
                    try:
                        self.server_authorization_token = wapt.get_auth_token('websocket')
                        logger.info('Websocket token: %s' % self.server_authorization_token)
                        connect_params['token'] = self.server_authorization_token
                    except Exception as e:
                        logger.warning('Websocket connect params: %s' % e)
                        self.server_authorization_token = None
                return {'params':connect_params,
                        'cert'  :(wapt.get_host_certificate_filename(),wapt.get_host_key_filename())}
            while True:
                try:
                    connect_params = get_connect_params(tmp_wapt)
                    if not self.socketio_client and self.config.websockets_host:
                        logger.debug('Creating socketio client')
                        logger.debug('Proxies : %s'%self.config.waptserver.proxies)
                        # bug in socketio... ? we must not pass proxies at all (even None) if we don"t want to switch to polling mode...
                        kwargs = {}
                        if self.config.waptserver.proxies and self.config.waptserver.proxies.get(self.config.websockets_proto,None) is not None:
                            kwargs['proxies'] = self.config.waptserver.proxies

                        kwargs.update(connect_params)
                        self.socketio_client = SocketIO(
                                host="%s://%s" % (self.config.websockets_proto,self.config.websockets_host),
                                port=self.config.websockets_port,
                                Namespace = WaptSocketIORemoteCalls,
                                resource=self.config.websockets_root,
                                verify=self.config.websockets_verify_cert,
                                wait_for_connection = False,
                                transport = ['websocket'],
                                ping_interval = self.config.websockets_ping,
                                hurry_interval_in_seconds = self.config.websockets_hurry_interval,
                                **kwargs)
                        self.socketio_client.get_namespace().wapt = tmp_wapt
                        self.socketio_client.get_namespace().task_manager = self.task_manager

                    if self.socketio_client and self.config.websockets_host:
                        if not self.socketio_client.connected:
                            self.socketio_client._http_session.update(connect_params)
                            self.socketio_client.define(WaptSocketIORemoteCalls)
                            self.socketio_client.get_namespace().wapt = tmp_wapt
                            self.socketio_client.get_namespace().task_manager = self.task_manager
                            self.socketio_client.connect('')
                        else:
                            # be sure server DB is aware of the current connection.
                            # could be avoided
                            self.socketio_client.emit('wapt_pong')

                        if self.socketio_client.connected:
                            logger.info('Socket IO listening for %ss' % self.config.websockets_check_config_interval )
                            startwait = time.time()
                            self.socketio_client.wait(self.config.websockets_check_config_interval)
                            # QAD workaround for cases where server disconnect but client is between 2 states.
                            # In this case; wait() immediately returns, leading to an indefinite loop eating 1 core.
                            if time.time() - startwait < self.config.websockets_check_config_interval-2:
                                raise Exception('Websocket client seems disconnected. Force Websocket connection to be recreated')

                    elif not self.config.websockets_host:
                        self.socketio_client = None
                        time.sleep(self.config.websockets_retry_delay)
                    else:
                        time.sleep(self.config.websockets_retry_delay)

                    if self.config.reload_if_updated():
                        tmp_wapt.reload_config_if_updated()
                        if self.socketio_client:
                            self.socketio_client.disconnect()
                        raise EWaptException('Configuration changed, force Websocket connection to be recreated')


                except Exception as e:
                    try:
                        # reset token
                        self.server_authorization_token = None
                        self.config.reload_if_updated()
                        if self.socketio_client:
                            self.socketio_client = None
                    finally:
                        logger.debug(u'Exception %s, Socket IO Stopped, waiting %ss before retrying' %
                            (repr(e),self.config.websockets_retry_delay))
                        time.sleep(self.config.websockets_retry_delay)
Exemple #10
0
class TestSocketIO(TestCase):
    def setUp(self):
        self.socketIO = SocketIO(HOST, PORT)
        self.called_on_response = False

    def tearDown(self):
        del self.socketIO

    def on_response(self, *args):
        self.called_on_response = True
        for arg in args:
            if isinstance(arg, dict):
                self.assertEqual(arg, PAYLOAD)
            else:
                self.assertEqual(arg, DATA)

    def is_connected(self, socketIO, connected):
        childThreads = [
            socketIO._rhythmicThread,
            socketIO._listenerThread,
        ]
        for childThread in childThreads:
            self.assertEqual(not connected, childThread.done.is_set())
        self.assertEqual(connected, socketIO.connected)

    def test_disconnect(self):
        'Terminate child threads after disconnect'
        self.is_connected(self.socketIO, True)
        self.socketIO.disconnect()
        self.is_connected(self.socketIO, False)
        # Use context manager
        with SocketIO(HOST, PORT) as self.socketIO:
            self.is_connected(self.socketIO, True)
        self.is_connected(self.socketIO, False)

    def test_message(self):
        'Message'
        self.socketIO.define(Namespace)
        self.socketIO.message()
        self.socketIO.wait(0.1)
        namespace = self.socketIO.get_namespace()
        self.assertEqual(namespace.response, 'message_response')

    def test_message_with_data(self):
        'Message with data'
        self.socketIO.define(Namespace)
        self.socketIO.message(DATA)
        self.socketIO.wait(0.1)
        namespace = self.socketIO.get_namespace()
        self.assertEqual(namespace.response, DATA)

    def test_message_with_payload(self):
        'Message with payload'
        self.socketIO.define(Namespace)
        self.socketIO.message(PAYLOAD)
        self.socketIO.wait(0.1)
        namespace = self.socketIO.get_namespace()
        self.assertEqual(namespace.response, PAYLOAD)

    def test_message_with_callback(self):
        'Message with callback'
        self.socketIO.message(callback=self.on_response)
        self.socketIO.wait_for_callbacks(seconds=0.1)
        self.assertEqual(self.called_on_response, True)

    def test_message_with_callback_with_data(self):
        'Message with callback with data'
        self.socketIO.message(DATA, self.on_response)
        self.socketIO.wait_for_callbacks(seconds=0.1)
        self.assertEqual(self.called_on_response, True)

    def test_emit(self):
        'Emit'
        self.socketIO.define(Namespace)
        self.socketIO.emit('emit')
        self.socketIO.wait(0.1)
        self.assertEqual(self.socketIO.get_namespace().argsByEvent, {
            'emit_response': (),
        })

    def test_emit_with_payload(self):
        'Emit with payload'
        self.socketIO.define(Namespace)
        self.socketIO.emit('emit_with_payload', PAYLOAD)
        self.socketIO.wait(0.1)
        self.assertEqual(self.socketIO.get_namespace().argsByEvent, {
            'emit_with_payload_response': (PAYLOAD, ),
        })

    def test_emit_with_multiple_payloads(self):
        'Emit with multiple payloads'
        self.socketIO.define(Namespace)
        self.socketIO.emit('emit_with_multiple_payloads', PAYLOAD, PAYLOAD)
        self.socketIO.wait(0.1)
        self.assertEqual(self.socketIO.get_namespace().argsByEvent, {
            'emit_with_multiple_payloads_response': (PAYLOAD, PAYLOAD),
        })

    def test_emit_with_callback(self):
        'Emit with callback'
        self.socketIO.emit('emit_with_callback', self.on_response)
        self.socketIO.wait_for_callbacks(seconds=0.1)
        self.assertEqual(self.called_on_response, True)

    def test_emit_with_callback_with_payload(self):
        'Emit with callback with payload'
        self.socketIO.emit('emit_with_callback_with_payload', self.on_response)
        self.socketIO.wait_for_callbacks(seconds=0.1)
        self.assertEqual(self.called_on_response, True)

    def test_emit_with_callback_with_multiple_payloads(self):
        'Emit with callback with multiple payloads'
        self.socketIO.emit('emit_with_callback_with_multiple_payloads',
                           self.on_response)
        self.socketIO.wait_for_callbacks(seconds=0.1)
        self.assertEqual(self.called_on_response, True)

    def test_emit_with_event(self):
        'Emit to trigger an event'
        self.socketIO.on('emit_with_event_response', self.on_response)
        self.socketIO.emit('emit_with_event', PAYLOAD)
        self.socketIO.wait_for_callbacks(0.1)
        self.assertEqual(self.called_on_response, True)

    def test_ack(self):
        'Trigger server callback'
        self.socketIO.define(Namespace)
        self.socketIO.emit('ack', PAYLOAD)
        self.socketIO.wait(0.1)
        self.assertEqual(self.socketIO.get_namespace().argsByEvent, {
            'ack_response': (PAYLOAD, ),
            'ack_callback_response': (PAYLOAD, ),
        })

    def test_namespaces(self):
        'Behave differently in different namespaces'
        mainNamespace = self.socketIO.define(Namespace)
        chatNamespace = self.socketIO.define(Namespace, '/chat')
        newsNamespace = self.socketIO.define(Namespace, '/news')
        newsNamespace.emit('emit_with_payload', PAYLOAD)
        self.socketIO.wait(0.1)
        self.assertEqual(mainNamespace.argsByEvent, {})
        self.assertEqual(chatNamespace.argsByEvent, {})
        self.assertEqual(newsNamespace.argsByEvent, {
            'emit_with_payload_response': (PAYLOAD, ),
        })