def test_ack(): # Create environment server, session, transport, conn = _get_test_environment() # Send message with ACK transport.recv(proto.message(None, 'abc', 1)) # Check that message was received by the connection eq_(conn.pop_incoming(), 'abc') # Check for ACK eq_(transport.pop_outgoing(), '3:::abc') eq_(transport.pop_outgoing(), '6:::1') # Send with ACK def handler(msg, data): eq_(msg, 'abc') eq_(data, None) conn.send('yes') conn.send('abc', handler) eq_(transport.pop_outgoing(), '3:1::abc') # Send ACK from client transport.recv('6:::1') # Check if handler was called eq_(transport.pop_outgoing(), '3:::yes') # Test ack with event # Send event with multiple parameters transport.recv(proto.event(None, 'test', 1, a=10, b=20)) # Check outgoing eq_(transport.pop_outgoing(), proto.event(None, 'test', None, a=10, b=20)) eq_(transport.pop_outgoing(), proto.ack(None, 1, 'test'))
def raw_message(self, msg): """Socket.IO message handler. `msg` Raw socket.io message to handle """ try: logging.debug('>>> ' + msg) parts = msg.split(':', 3) if len(parts) == 3: msg_type, msg_id, msg_endpoint = parts msg_data = None else: msg_type, msg_id, msg_endpoint, msg_data = parts # Packets that don't require valid endpoint if msg_type == proto.DISCONNECT: if not msg_endpoint: self.close() else: self.disconnect_endpoint(msg_endpoint) return elif msg_type == proto.CONNECT: if msg_endpoint: self.connect_endpoint(msg_endpoint) else: # TODO: Disconnect? logging.error('Invalid connect without endpoint') return # All other packets need endpoints conn = self.get_connection(msg_endpoint) if conn is None: logging.error('Invalid endpoint: %s' % msg_endpoint) return if msg_type == proto.HEARTBEAT: self._missed_heartbeats = 0 elif msg_type == proto.MESSAGE: # Handle text message conn.on_message(msg_data) if msg_id: self.send_message(proto.ack(msg_endpoint, msg_id)) elif msg_type == proto.JSON: # Handle json message conn.on_message(proto.json_load(msg_data)) if msg_id: self.send_message(proto.ack(msg_endpoint, msg_id)) elif msg_type == proto.EVENT: # Javascript event event = proto.json_load(msg_data) # TODO: Verify if args = event.get('args', []) won't be slower. args = event.get('args') if args is None: args = [] ack_response = None # It is kind of magic - if there's only one parameter # and it is dict, unpack dictionary. Otherwise, pass # in args if len(args) == 1 and isinstance(args[0], dict): # Fix for the http://bugs.python.org/issue4978 for older Python versions str_args = dict( (str(x), y) for x, y in args[0].iteritems()) ack_response = conn.on_event(event['name'], kwargs=str_args) else: ack_response = conn.on_event(event['name'], args=args) if msg_id: if msg_id.endswith('+'): msg_id = msg_id[:-1] self.send_message( proto.ack(msg_endpoint, msg_id, ack_response)) elif msg_type == proto.ACK: # Handle ACK ack_data = msg_data.split('+', 2) data = None if len(ack_data) > 1: data = proto.json_load(ack_data[1]) conn.deque_ack(int(ack_data[0]), data) elif msg_type == proto.ERROR: # TODO: Pass it to handler? logging.error('Incoming error: %s' % msg_data) elif msg_type == proto.NOOP: pass except Exception, ex: logging.exception(ex) # TODO: Add global exception callback? raise
def raw_message(self, msg): """Socket.IO message handler. `msg` Raw socket.io message to handle """ try: logging.debug('>>> ' + msg) parts = msg.split(':', 3) if len(parts) == 3: msg_type, msg_id, msg_endpoint = parts msg_data = None else: msg_type, msg_id, msg_endpoint, msg_data = parts # Packets that don't require valid endpoint if msg_type == proto.DISCONNECT: if not msg_endpoint: self.close() else: self.disconnect_endpoint(msg_endpoint) return elif msg_type == proto.CONNECT: if msg_endpoint: self.connect_endpoint(msg_endpoint) else: # TODO: Disconnect? logging.error('Invalid connect without endpoint') return # All other packets need endpoints conn = self.get_connection(msg_endpoint) if conn is None: logging.error('Invalid endpoint: %s' % msg_endpoint) return if msg_type == proto.HEARTBEAT: self._missed_heartbeats = 0 elif msg_type == proto.MESSAGE: # Handle text message conn.on_message(msg_data) if msg_id: self.send_message(proto.ack(msg_endpoint, msg_id)) elif msg_type == proto.JSON: # Handle json message conn.on_message(proto.json_load(msg_data)) if msg_id: self.send_message(proto.ack(msg_endpoint, msg_id)) elif msg_type == proto.EVENT: # Javascript event event = proto.json_load(msg_data) # TODO: Verify if args = event.get('args', []) won't be slower. args = event.get('args') if args is None: args = [] ack_response = None # It is kind of magic - if there's only one parameter # and it is dict, unpack dictionary. Otherwise, pass # in args if len(args) == 1 and isinstance(args[0], dict): # Fix for the http://bugs.python.org/issue4978 for older Python versions str_args = dict((str(x), y) for x, y in args[0].iteritems()) ack_response = conn.on_event(event['name'], kwargs=str_args) else: ack_response = conn.on_event(event['name'], args=args) if msg_id: if msg_id.endswith('+'): msg_id = msg_id[:-1] self.send_message(proto.ack(msg_endpoint, msg_id, ack_response)) elif msg_type == proto.ACK: # Handle ACK ack_data = msg_data.split('+', 2) data = None if len(ack_data) > 1: data = proto.json_load(ack_data[1]) conn.deque_ack(int(ack_data[0]), data) elif msg_type == proto.ERROR: # TODO: Pass it to handler? logging.error('Incoming error: %s' % msg_data) elif msg_type == proto.NOOP: pass except Exception, ex: logging.exception(ex) # TODO: Add global exception callback? raise
def raw_message(self, msg): """Socket.IO message handler. `msg` Raw socket.io message to process. """ try: logging.debug('>>> ' + msg) parts = msg.split(':', 3) if len(parts) == 3: msg_type, msg_id, msg_endpoint = parts msg_data = None else: msg_type, msg_id, msg_endpoint, msg_data = parts # Packets that don't require valid endpoint if msg_type == proto.DISCONNECT: if not msg_endpoint: self.close() else: self.disconnect_endpoint(msg_endpoint) return elif msg_type == proto.CONNECT: if msg_endpoint: self.connect_endpoint(msg_endpoint) else: # TODO: Disconnect? logging.error('Invalid connect without endpoint') return # All other packets need endpoints conn = self.get_connection(msg_endpoint) if conn is None: logging.error('Invalid endpoint: %s' % msg_endpoint) return if msg_type == proto.HEARTBEAT: self._missed_heartbeats = 0 elif msg_type == proto.MESSAGE: # Handle text message conn.on_message(msg_data) if msg_id: self.send_message(proto.ack(msg_endpoint, msg_id)) elif msg_type == proto.JSON: # Handle json message conn.on_message(proto.json_load(msg_data)) if msg_id: self.send_message(proto.ack(msg_endpoint, msg_id)) elif msg_type == proto.EVENT: # Javascript event event = proto.json_load(msg_data) args = event['args'] # It is kind of magic - if there's only one parameter # and it is dict, unpack dictionary. Otherwise, pass # as *args if len(args) == 1 and isinstance(args[0], dict): conn.on_event(event['name'], **args[0]) else: conn.on_event(event['name'], *args) if msg_id: self.send_message(proto.ack(msg_endpoint, msg_id)) elif msg_type == proto.ACK: # Handle ACK ack_data = msg_data.split('+', 2) # TODO: Support custom data sent from the server conn.deque_ack(int(ack_data[0])) elif msg_type == proto.ERROR: # TODO: Pass it to handler? logging.error('Incoming error: %s' % msg_data) elif msg_type == proto.NOOP: pass except Exception, ex: logging.exception(ex) # TODO: Add global exception callback? raise