Receiving Events
This guide covers how you can correctly receive and interpret events as part of integrating with the Reporting API.
The C# examples in this tutorial use the protobuf-net Nuget package.
Event Queues
RabbitMQ supplies events via two queues.
rabbit.spot_queueis used for receiving spot events (and only spot events).rabbit.queueis used for receiving all other types of events.
Note that rabbit.spot_queue is not available by default. You can enable it by contacting Spotware's service assurance team.
Structure of Events
Each event contains the following information.
| Name | Definition |
|---|---|
Payload | The contents of the Protobuf message as a byte array |
Properties | The properties of the object representing the delivered message. Properties contain the following information.
|
In brief, accessing the contents of an event requires the following.
- Determining the
messageTypeof the newly received message via theheaders.messageTypeproperty. - Converting the message payload into a suitable class representing the
messageTypereceived during Step 1.
If you already know the messageType of an event, you can access its contents as follows (the examples below use TraderGroupEvent).
- C#
- Java
TraderGroupEvent event = Serializer.Deserialize(TraderGroupEvent, message.Body);
TraderGroupEvent event = TraderGroupEvent.parseFrom(message.getPayload());
Each queue has limits on how many events it can hold and for how long it can hold them in case of a client losing its connection with our RabbitMQ node. All events that meet these limits are stored on our side and are sent to your client as soon as connection is restored. However, events that exceed these limits will be essentially lost. If your connection to RabbitMQ is dropped, please validate all newly received events by their spotware-sequence-number and reconcile if you detect that some events have been missed.
Initiating Message Consumption
After establishing a connection with RabbitMQ, you should be ready to receive events from rabbit.queue and, optionally, rabbit.spot_queue. To do so, perform the following actions.
- Create a consumer object.
- Subscribe the consumer to suitable handlers of the
Receivedevent. - From your
channelobject, call a valid method for initiating message consumption.
Here are two simple examples of how you can start receiving and processing messages.
- C#
- Java
/* the NAMESPACE string should contain all qualifiers required
to access the classes representing various Protobuf message types*/
const string NAMESPACES = ...;
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
string messageType = Encoding.UTF8.GetString((byte[])ea.BasicProperties.Headers["messageType"]);
long sequenceNumber = Convert.ToInt64(ea.BasicProperties.Headers["spotware-sequence-number"]);
// the Type.GetType() method requires passing a fully qualified class name
var message = Serializer.Deserialize(Type.GetType('{NAMESPACES}.{messageType}'), ea.Body);
// additional logics depending on the message type
};
channel.BasicConsume(userName, true, consumer);
/* type2Message is a map where strings containing message types are keys
and any message type can be a value */
static final Map<String, ? extends Message>> type2Message = ...
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String messageType = delivery.getProperties().getHeaders().get("messageType");
var message = type2message.get(messageType).parseFrom(delivery.getPayload());
var sequenceNumber = Long.valueOf(delivery.getProperties().getHeaders().get("spotware-sequence-number"));
// additional logics depending on the message type
};
channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });