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 )
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
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)
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)
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)
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()
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)
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, ), })