Utilizzo delle API di messaggistica - AWS SimSpace Weaver

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Utilizzo delle API di messaggistica

Le API di messaggistica sono contenute nell'SDK dell'SimSpace Weaverapp (versione minima 1.16.0). La messaggistica è supportata in C++, Python e nelle nostre integrazioni con Unreal Engine 5 e Unity.

Esistono due funzioni che gestiscono le transazioni di messaggi: e. SendMessage ReceiveMessages Tutti i messaggi inviati contengono una destinazione e un payload. L'ReceiveMessagesAPI restituisce un elenco di messaggi attualmente presenti nella coda dei messaggi in entrata di un'app.

C++

Invia messaggio

AWS_WEAVERRUNTIME_API Result<void> SendMessage( Transaction& txn, const MessagePayload& payload, const MessageEndpoint& destination, MessageDeliveryType deliveryType = MessageDeliveryType::BestEffort ) noexcept;

Ricevere messaggi

AWS_WEAVERRUNTIME_API Result<MessageList> ReceiveMessages( Transaction& txn) noexcept;
Python

Inviare un messaggio

api.send_message( txn, # Transaction payload, # api.MessagePayload destination, # api.MessageDestination api.MessageDeliveryType.BestEffort # api.MessageDeliveryType )

Ricevere messaggi

api.receive_messages( txn, # Transaction ) -> api.MessageList

Invio di messaggi

I messaggi sono costituiti da una transazione (simile ad altre chiamate dell'API Weaver), un payload e una destinazione.

Payload del messaggio

Il payload dei messaggi è una struttura dati flessibile fino a 256 byte. Consigliamo quanto segue come best practice per creare i payload dei messaggi.

Per creare il payload dei messaggi
  1. Crea una struttura di dati (ad esempio struct in C++) che definisca il contenuto del messaggio.

  2. Crea il payload del messaggio che contiene i valori da inviare nel messaggio.

  3. Crea l'MessagePayloadoggetto.

Destinazione del messaggio

La destinazione di un messaggio è definita dall'MessageEndpointoggetto. Ciò include sia un tipo di endpoint che un ID di endpoint. L'unico tipo di endpoint attualmente supportato èPartition, che consente di indirizzare messaggi ad altre partizioni nella simulazione. L'ID endpoint è l'ID di partizione della destinazione di destinazione.

Puoi fornire solo 1 indirizzo di destinazione in un messaggio. Crea e invia più messaggi se desideri inviare messaggi a più di 1 partizione contemporaneamente.

Per indicazioni su come risolvere un endpoint di messaggio da una posizione, vedere. Suggerimenti per l'utilizzo della messaggistica

Inviare il messaggio

È possibile utilizzare l'SendMessageAPI dopo aver creato gli oggetti di destinazione e di payload.

C++
Api::SendMessage(transaction, payload, destination, MessageDeliveryType::BestEffort);
Python
api.send_message(txn, payload, destination, api.MessageDeliveryType.BestEffort)
Esempio completo di invio di messaggi

L'esempio seguente mostra come è possibile costruire e inviare un messaggio generico. Questo esempio invia 16 messaggi singoli. Ogni messaggio contiene un payload con un valore compreso tra 0 e 15 e il segno di spunta di simulazione corrente.

C++
// Message struct definition struct MessageTickAndId { uint32_t id; uint32_t tick; }; Aws::WeaverRuntime::Result<void> SendMessages(Txn& txn) noexcept { // Fetch the destination MessageEndpoint with the endpoint resolver WEAVERRUNTIME_TRY( Api::MessageEndpoint destination, Api::Utils::MessageEndpointResolver::ResolveFromPosition( txn, "MySpatialSimulation", Api::Vector2F32 {231.3, 654.0} ) ); Log::Info("destination: ", destination); WEAVERRUNTIME_TRY(auto tick, Api::CurrentTick(txn)); uint16_t numSentMessages = 0; for (std::size_t i=0; i<16; i++) { // Create the message that'll be serialized into payload MessageTickAndId message {i, tick.value}; // Create the payload out of the struct const Api::MessagePayload& payload = Api::Utils::CreateMessagePayload( reinterpret_cast<const std::uint8_t*>(&message), sizeof(MessageTickAndId) ); // Send the payload to the destination Result<void> result = Api::SendMessage(txn, payload, destination); if (result.has_failure()) { // SendMessage has failure modes, log them auto error = result.as_failure().error(); std::cout<< "SendMessage failed, ErrorCode: " << error << std::endl; continue; } numSentMessages++; } std::cout << numSentMessages << " messages is sent to endpoint" << destination << std::endl; return Aws::WeaverRuntime::Success(); }
Python
# Message data class @dataclasses.dataclass class MessageTickAndId: tick: int = 0 id: int = 0 # send messages def _send_messages(self, txn): tick = api.current_tick(txn) num_messages_to_send = 16 # Fetch the destination MessageEndpoint with the endpoint resolver destination = api.utils.resolve_endpoint_from_domain_name_position( txn, "MySpatialSimulation", pos ) Log.debug("Destination_endpoint = %s", destination_endpoint) for id in range(num_messages_to_send): # Message struct that'll be serialized into payload message_tick_and_id = MessageTickAndId(id = id, tick = tick.value) # Create the payload out of the struct message_tick_and_id_data = struct.pack( '<ii', message_tick_and_id.id, message_tick_and_id.tick ) payload = api.MessagePayload(list(message_tick_and_id_data)) # Send the payload to the destination Log.debug("Sending message: %s, endpoint: %s", message_tick_and_id, destination ) api.send_message( txn, payload, destination, api.MessageDeliveryType.BestEffort ) Log.info("Sent %s messages to %s", num_messages_to_send, destination) return True

Ricezione di messaggi

SimSpace Weaverconsegna i messaggi nella coda dei messaggi in entrata di una partizione. Utilizza l'ReceiveMessagesAPI per ottenere un MessageList oggetto che contiene i messaggi dalla coda. Elabora ogni messaggio con l'ExtractMessageAPI per ottenere i dati del messaggio.

C++
Result<void> ReceiveMessages(Txn& txn) noexcept { // Fetch all the messages sent to the partition owned by the app WEAVERRUNTIME_TRY(auto messages, Api::ReceiveMessages(txn)); std::cout << "Received" << messages.messages.size() << " messages" << std::endl; for (Api::Message& message : messages.messages) { std::cout << "Received message: " << message << std::endl; // Deserialize payload to the message struct const MessageTickAndId& receivedMessage = Api::Utils::ExtractMessage<MessageTickAndId>(message); std::cout << "Received MessageTickAndId, Id: " << receivedMessage.id <<", Tick: " << receivedMessage.tick << std::endl; } return Aws::WeaverRuntime::Success(); }
Python
# process incoming messages def _process_incoming_messages(self, txn): messages = api.receive_messages(txn) for message in messages: payload_list = message.payload.data payload_bytes = bytes(payload_list) message_tick_and_id_data_struct = MessageTickAndId(*struct.unpack('<ii', payload_bytes)) Log.debug("Received message. Header: %s, message: %s", message.header, message_tick_and_id_data_struct) Log.info("Received %s messages", len(messages)) return True

Rispondere al mittente

Ogni messaggio ricevuto contiene un'intestazione del messaggio con informazioni sul mittente originale del messaggio. Puoi usare message.header.source_endpoint per inviare una risposta.

C++
Result<void> ReceiveMessages(Txn& txn) noexcept { // Fetch all the messages sent to the partition owned by the app WEAVERRUNTIME_TRY(auto messages, Api::ReceiveMessages(txn)); std::cout << "Received" << messages.messages.size() << " messages" << std::endl; for (Api::Message& message : messages.messages) { std::cout << "Received message: " << message << std::endl; // Deserialize payload to the message struct const MessageTickAndId& receivedMessage = Api::Utils::ExtractMessage<MessageTickAndId>(message); std::cout << "Received MessageTickAndId, Id: " << receivedMessage.id <<", Tick: " << receivedMessage.tick << std::endl; // Get the sender endpoint and payload to bounce the message back Api::MessageEndpoint& sender = message.header.source_endpoint; Api::MessagePayload& payload = message.payload; Api::SendMessage(txn, payload, sender); } return Aws::WeaverRuntime::Success(); }
Python
# process incoming messages def _process_incoming_messages(self, txn): messages = api.receive_messages(txn) for message in messages: payload_list = message.payload.data payload_bytes = bytes(payload_list) message_tick_and_id_data_struct = MessageTickAndId(*struct.unpack('<ii', payload_bytes)) Log.debug("Received message. Header: %s, message: %s", message.header, message_tick_and_id_data_struct) # Get the sender endpoint and payload # to bounce the message back sender = message.header.source_endpoint payload = payload_list api.send_message( txn, payload_list, sender, api.MessageDeliveryType.BestEffort Log.info("Received %s messages", len(messages)) return True