def process(self, value: COMMANDS) -> None: if isinstance(value, commands.Connection.Start): self._set_state(STATE_START_RECEIVED) self._process_start(value) elif isinstance(value, commands.Connection.Tune): self._set_state(STATE_TUNE_RECEIVED) self._process_tune(value) elif isinstance(value, commands.Connection.OpenOk): self._set_state(STATE_OPENOK_RECEIVED) elif isinstance(value, commands.Connection.Blocked): self._set_state(STATE_BLOCKED_RECEIVED) self.blocked.set() elif isinstance(value, commands.Connection.Unblocked): self._set_state(STATE_UNBLOCKED_RECEIVED) self.blocked.clear() elif isinstance(value, commands.Connection.Close): self._set_state(STATE_CLOSE_RECEIVED) self._transport.write( frame.marshal(commands.Connection.CloseOk(), 0)) self._set_state(STATE_CLOSEOK_SENT) self._on_remote_close(value.reply_code, value.reply_text) elif isinstance(value, commands.Connection.CloseOk): self._set_state(STATE_CLOSEOK_RECEIVED) elif isinstance(value, heartbeat.Heartbeat): self._set_state(STATE_HEARTBEAT_RECEIVED) self._last_heartbeat = self._loop.time() self._transport.write(frame.marshal(heartbeat.Heartbeat(), 0)) self._set_state(STATE_HEARTBEAT_SENT) else: self._set_state( state.STATE_EXCEPTION, exceptions.AIORabbitException( 'Unsupported Frame Passed to Channel0'))
def unmarshal(data_in): """Takes in binary data and maps builds the appropriate frame type, returning a frame object. :param bytes data_in: Raw byte stream data :rtype: tuple of bytes consumed, channel, and a frame object :raises: specification.FrameError """ # Look to see if it's a protocol header frame try: frame_value = _unmarshal_protocol_header_frame(data_in) if frame_value: return 8, 0, frame_value except ValueError as error: raise exceptions.UnmarshalingException(header.ProtocolHeader, error) # Decode the low level frame and break it into parts try: frame_type, channel_id, frame_size = _frame_parts(data_in) # Heartbeats do not have frame length indicators if frame_type == specification.FRAME_HEARTBEAT and frame_size == 0: return 8, channel_id, heartbeat.Heartbeat() if not frame_size: raise exceptions.UnmarshalingException('Unknown', 'No frame size') byte_count = FRAME_HEADER_SIZE + frame_size + 1 if byte_count > len(data_in): raise exceptions.UnmarshalingException('Unknown', 'Not all data received') if data_in[byte_count - 1] != DECODE_FRAME_END_CHAR: raise exceptions.UnmarshalingException('Unknown', 'Last byte error') frame_data = data_in[FRAME_HEADER_SIZE:byte_count - 1] except ValueError as error: raise exceptions.UnmarshalingException('Unknown', error) # Decode a method frame if frame_type == specification.FRAME_METHOD: return byte_count, channel_id, _unmarshal_method_frame(frame_data) # Decode a header frame elif frame_type == specification.FRAME_HEADER: return byte_count, channel_id, _unmarshal_header_frame(frame_data) # Decode a body frame elif frame_type == specification.FRAME_BODY: return byte_count, channel_id, _unmarshal_body_frame(frame_data) raise exceptions.UnmarshalingException( 'Unknown', 'Unknown frame type: %i' % frame_type)
def on_frame(self, value): """Process a RPC frame received from the server :param pamqp.message.Message value: The message value """ LOGGER.debug('Received frame: %r', value) if value.name == 'Connection.Close': LOGGER.warning('RabbitMQ closed the connection (%s): %s', value.reply_code, value.reply_text) self._set_state(self.CLOSED) self._events.set(events.SOCKET_CLOSE) self._events.set(events.CHANNEL0_CLOSED) if value.reply_code in exceptions.AMQP: err = exceptions.AMQP[value.reply_code](value.reply_text) else: err = exceptions.RemoteClosedException(value.reply_code, value.reply_text) self._exceptions.put(err) self._trigger_write() elif value.name == 'Connection.Blocked': LOGGER.warning('RabbitMQ has blocked the connection: %s', value.reason) self._events.set(events.CONNECTION_BLOCKED) elif value.name == 'Connection.CloseOk': self._set_state(self.CLOSED) self._events.set(events.CHANNEL0_CLOSED) elif value.name == 'Connection.OpenOk': self._on_connection_open_ok() elif value.name == 'Connection.Start': self._on_connection_start(value) elif value.name == 'Connection.Tune': self._on_connection_tune(value) LOGGER.debug('Adding frame to read queue: %r', value) elif value.name == 'Connection.Unblocked': LOGGER.info('Connection is no longer blocked') self._events.clear(events.CONNECTION_BLOCKED) elif value.name == 'Heartbeat': LOGGER.debug('Received Heartbeat, sending one back') self._write_frame(heartbeat.Heartbeat()) self._trigger_write() self._last_heartbeat = time.time() else: LOGGER.warning('Unexpected Channel0 Frame: %r', value) raise specification.AMQPUnexpectedFrame(value)
def unmarshal(data_in: bytes) -> typing.Tuple[int, int, FrameTypes]: """Takes in binary data and maps builds the appropriate frame type, returning a frame object. :returns: tuple of bytes consumed, channel, and a frame object :raises: exceptions.UnmarshalingException """ try: # Look to see if it's a protocol header frame value = _unmarshal_protocol_header_frame(data_in) except ValueError as error: raise exceptions.UnmarshalingException(header.ProtocolHeader, error) else: if value: return 8, 0, value frame_type, channel_id, frame_size = _frame_parts(data_in) # Heartbeats do not have frame length indicators if frame_type == constants.FRAME_HEARTBEAT and frame_size == 0: return 8, channel_id, heartbeat.Heartbeat() if not frame_size: raise exceptions.UnmarshalingException('Unknown', 'No frame size') byte_count = constants.FRAME_HEADER_SIZE + frame_size + 1 if byte_count > len(data_in): raise exceptions.UnmarshalingException('Unknown', 'Not all data received') if data_in[byte_count - 1] != constants.FRAME_END: raise exceptions.UnmarshalingException('Unknown', 'Last byte error') frame_data = data_in[constants.FRAME_HEADER_SIZE:byte_count - 1] if frame_type == constants.FRAME_METHOD: return byte_count, channel_id, _unmarshal_method_frame(frame_data) elif frame_type == constants.FRAME_HEADER: return byte_count, channel_id, _unmarshal_header_frame(frame_data) elif frame_type == constants.FRAME_BODY: return byte_count, channel_id, _unmarshal_body_frame(frame_data) raise exceptions.UnmarshalingException( 'Unknown', 'Unknown frame type: {}'.format(frame_type))
def test_heartbeat(self): expectation = b'\x08\x00\x00\x00\x00\x00\x00\xce' response = frame.marshal(heartbeat.Heartbeat(), 0) self.assertEqual(response, expectation, 'Heartbeat did not match expectation')
def test_heartbeat(self): self.loop.run_until_complete(self.open()) self.assert_state(channel0.STATE_OPENOK_RECEIVED) self.channel0.process(heartbeat.Heartbeat()) self.assert_state(channel0.STATE_HEARTBEAT_SENT) self.assertTrue(self.heartbeat.is_set())
def send_heartbeat(self): """Send a heartbeat frame to the remote connection.""" self.write_frame(heartbeat.Heartbeat())
def heartbeat_test(self): expectation = encode('\x08\x00\x00\x00\x00\x00\x00\xce') response = frame.marshal(heartbeat.Heartbeat(), 0) self.assertEqual(response, expectation, "Heartbeat did not match expectation")