-
Notifications
You must be signed in to change notification settings - Fork 20
Observe Example
CoAP has the concept of allowing for a client to observe a resource on a server and have the server send notifications to the client when the state has changed. This is documented in RFC 7641.
There are several different ways that the library can be used to setup an observe relationship with a server.
Using the CoapClient class
The CoapClient class provides a set of functions that can be used to initiate an observe relationship. Using this class provides some additionally functionality such as filtering the notification stream for duplicate events.
CoapClient client = new CoapClient(new Uri("coaps://example.com/resource"));
client.Observe(NotifyEvent, FailEvent);
The events are called when specific conditions are met. The notification event is called when a new message arrives and the system determines that it neither a duplicate event or a past event. The default method is used the algorithm laid out in RFC 7641 Section 3.4. The configuration parameter NotificationMaxAge can be modified to change this. The method itself can be changed via the [CoapObserveRelation] returned by the observe method.
An example notification event function is
static void NotifyEvent(Response res)
{
Console.WriteLine("The notify number {1} has a payload of {0}", res.ResponseText, res.Observe);
}
It should be noted that the notify event has the response, but does not have any user context. This can be solved by the use of delegate functions. Thus the observe method would be called using
coap.Observe(r => { NotifyEvent(contextObject, r); }, r=> { FailEvent(contextObject, r); });
One can also directly hit the context object as well by using
coap.Observe( r => { contextObject.ObserveNotify(r); });
If you want to have more complete control over processing, one can use the Response class directly to do observation of resources.
Request request = new Request(METHOD.GET);
request.MarkObserve();
request.Respond += ResponseMethod;
request.Send();
Again, one can use a delegate for the response method to include context if desired
request.Respond += delegate(Object sender, ResponseEventArgs e)
{
Response response = e.Response;
if (response == null) {
Console.WriteLine("Request timeout");
}
else {
contextObject.ObserveNotify(response);
}
}
The library will do automatic re-connection if a sufficient amount of time has passed since the last notification message was received. The amount of time is controlled by the Max-Age option that the server returns. If there is no option then it will be defaulted to 60 seconds. However, a well behaved server will generally specify a value. For example, my IKEA Trådfr sends a value of 604800 seconds (or 168 hours).
When using a request, the reconnect behavior can be turned off with the ObserveReconnect property on the request.
There are some additional items that need to be highlighted.
-
Firewalls are not always your friend. Under normal circumstances using a random port for the client can lead to the firewall blocking notifications back to the client. This may occur in as short as 62 seconds for some versions of windows. For this reason, an endpoint should be created with a port which is not ephemeral.
-
There is no standardized method for a server to notify a client that it is not going to send any more updates.
-
Coming soon - the ability to pass in a context object to the observe function.