QoS - Server Sample
This section will show how QoS
from the server-side works.
All extension-methods for sending data (RPC
& Pub/Sub
) can take QoS
as a parameter. If QoS
is set to AtLeastOnce
the server will store the message and resend it to the client until the client acknowledge the message.
The server will only care about the QoS
level for clients that support QoS
. So if the client does not claim to understand QoS
the message will be sent with level FireAndForget
.
QoS Level 1
In this sample we will use Putty
to fake the scenario. We will open 3 connections. One producer (sensor) and two consumers (monitors). Only one of the consumers will claim to understanding QoS
. So the message sent from the server will be re-sent until the Putty client sends back the acknowledgment for the message-ID.
To see this in action we add a message-interceptor
to see messages going in/out of the server.
Message Interceptor
This is just to be able to see the message-flow
public class MyMessageInterceptor : IMessageInterceptor
{
public void OnIncomingMessage(IXSocketProtocol protocol, IMessage message)
{
Composable.GetExport<IXLogger>().Information("In: {@m}", message);
}
public void OnOutgoingMessage(IXSocketProtocol protocol, IMessage message)
{
Composable.GetExport<IXLogger>().Information("Out: {@m}", message);
}
}
Controllers
We will use 2 controllers in this sample.
Monitor
: A controllers that monitoring clients connect to.
Sensor
: A controller that sensors connect to.
When the Sensor controller receives a message it will send the message to all clients connected to the Monitor
controller. The message will be sent with QoS
set to AtLeastOnce
. This means that the server will re-send the message to the clients that supports QoS
until they acknowledge the message.
Monitor
Very simple since we do not have any logic in this controller
public class Monitor : XSocketController
{
}
Sensor
Has one method (temp) that will take a double and send it to the clients using the Monitor
controller. Do note that we use RPC
here, but Pub/Sub
will work as well.
public class Sensor : XSocketController
{
public async Task Temp(double t)
{
await this.InvokeToAll<Monitor>(t, "temp", QoS.AtLeastOnce);
}
}
Test
Now when we send in a message with QoS Level 1
to the client we expect the client to acknowledge that message. So we should see a message going out with QoS = 1
and then the client should respond with a MsgAck
to a message with the same ID.
Since we use Putty
we will have to do the MsgAck
manually. The clients that support QoS
will of course handle this for you. Doing this manually will help to understand how things work.
So now we open up 3 instances of Putty
. The first instance will act as a sensor and connect to the Sensor
controller. The other instances will use the Monitor
controller, but only one of them will claim to understand QoS
.
Sensor Client
The fake sensor connects to the Sensor
controller and sends in a temp of 25.3
Monitor Client
Below you can see two client connecting to the Monitor
controller via Putty
. The difference between them is that one of them claim to understand QoS
by sending in QoS=1
in the handshake. This means that the server will treat the client as a QoS-capable
client and store/re-send messages with QoS > 0
for the client.
This is seen below since the QoS
enabled client gets messages until it finally acknowledge the message by sending monitor|msgack|1
. The 1 represents the message-ID to acknowledge.
Client - QoS Enabled Note that the message was re-sent until the client acknowledged the message
Client - QoS Disabled No QoS, and the message was received once with no need for acknowledgment.
Server Log Output
The server log shows that the connection with QoS
gets the message delivered until the acknowledgment is received at the server.
- IN: The server receives the sensor data
- OUT: The server sends out the temp value to both client on the
Monitor
controller - OUT: The server then re-send the message 2 more times to the client wth QoS enabled since no MsgAck has been received
- IN: The server receives the MsgAck for the message and stop sending messages out.