|
|
## Introduction
|
|
|
|
|
|
This document proposes a protocol for sensor subscriptions. The use case is as follows:
|
|
|
|
|
|
A dataspace node (the subscriber) wants to automatically receive sensor nodes from a sensor provided by a different node (the publisher). To do so, the subscriber subscribes himself to the publisher's sensor. When the sensor provides a new sensor reading, the publisher will forward it to the subscriber. When the subscriber is no longer interested in the sensor, he unsubscribes himself. The publisher will no longer send new readings to him. Subscriptions are expected to persist between reboots and when the subscriber or the publisher is offline.
|
|
|
|
|
|
The protocol is specified below. All messages are sent via drasyl. When a message is received which is not expected by the protocol, it is ignored by the receiving node.
|
|
|
|
|
|
## Messages
|
|
|
|
|
|
There are the following messages:
|
|
|
- `SUBSCRIBE`: used to subscribe to another node
|
|
|
- `UNSUBSCRIBE`: used to revoke a previous subscription
|
|
|
- `SUCCESS`: indicates that a subscription was successful
|
|
|
- `FAILED`: indicates that a subscription failed because of some failure at the publisher or during transmission; retrying the subscription might be beneficial
|
|
|
- `UNAVAILABLE`: indicates that a subscription failed because the publisher does not recognize the requested sensor; retrying the subscription would lead to the same result
|
|
|
- `READING`: used to transmit sensor readings from publishers to subscribers
|
|
|
|
|
|
All messages have the following format:
|
|
|
|
|
|
- `sender`: drasyl address of the message's sender
|
|
|
- `receiver`: drasyl address of the message's receiver
|
|
|
- `sensorId`: ID of the concerned sensor
|
|
|
|
|
|
Additionally, `READING` messages contain a field `reading` which stores the transmitted sensor reading.
|
|
|
|
|
|
If a node receives a message whose `receiver` address does not match the node's own address, the message is ignored.
|
|
|
|
|
|
## Subscription Management Protocol
|
|
|
|
|
|
This protocol is used to establish, maintain, and revoke subscriptions. It is specified by the following state machine:
|
|
|
|
|
|

|
|
|
|
|
|
Subscriptions are established with a 2-way-handshake.
|
|
|
|
|
|
Active subscriptions are stored in the database of each node as tuples `(subscriber-address, publisher-address, sensor-ID)`. `subscriber-address` is the drasyl address of the subscriber, `publisher-address` is the drasyl address of the publisher, and `sensor-ID` is the ID of the concerned sensor. The database is used by the notification protocol to lookup active subscriptions. Additionally, storing subscriptions in the database persists them across reboots.
|
|
|
|
|
|
In order to subscribe to a sensor, the subscriber sends a `SUBSCRIBE` message containing its own and the publisher's address as well as the concerned sensor ID to the publisher. Then, it waits for an appropriate response (state `Subscribing`). A response message must concern the same sensor ID and it must have matching sender and receiver addresses. To deal with network failures, a timeout mechanism is used (`TIMEOUT`). The subscription process is a critical section, i.e. no other subscription can be issued at the same time. This ensures that a response to one subscription procedure is dropped by the another one.
|
|
|
|
|
|
After receiving a response or timeout, the subscriber switches to the next state. The subscriber can immediately switch from the `Subscribed` to the `Pending` state. In the case of the states `Unavailable` and `Failed` the causing error/failure must be handled appropriately before switching back to `Pending`. In the case of `Unavailable`, informing the caller about the error is sufficient. In the `Failed` state, handling DB or network problems might be required.
|
|
|
Similar error handling is present at the publisher side.
|
|
|
|
|
|
When the publisher receives a `SUBSCRIPTION` message, it checks whether it has a local sensor with the requested sensor ID (`Processing` state). If the sensor ID is not recognized, the publisher responds with an `UNAVAILABLE` message. If some failure (e.g. a DB failure) occurs during the processing, it responds with a `FAILED` message. If the requested sensor can be provided, it stores the subscription in its local database and responds with a `SUCCESS` message.
|
|
|
|
|
|
When the publisher receives an `UNSUBSCRIBE` message, it deletes the matching subscription (if one exists) from its database.
|
|
|
|
|
|
## Notification Protocol
|
|
|
|
|
|
This protocol defines how publishers notify subscribers about new sensor readings of sensors they have subscribed to. It is specified by the following state machine:
|
|
|
|
|
|

|
|
|
|
|
|
When a node receives a new sensor reading from one of its local sensors, it looks in its local database whether any subscribers exist for the given sensor. If none are present, nothing further happens. If some subscribers are present, the new reading is sent to each subscriber via a `READING` message.
|
|
|
|
|
|
When a node receives a `READING` message, it checks whether its local database contains a matching subscription. If it does, the reading is processed internally. If it does not, the node responds with an `UNSUBSCRIBE` message. This ensures that publisher's are informed about unsubscriptions when the initial unsubscription was not received (for instance, because the publisher was offline at the time).
|
|
|
|
|
|
Any node that is subscribed to another node may revoke this subscription at any time. To do so, the subscription is deleted from its local database and an `UNSUBSCRIBE` message is sent to the corresponding publisher.
|
|
|
|
|
|
## Further Details on the Design
|
|
|
|
|
|
The order of database operations and message sending during the subscription process is important. Firstly, the subscriber stores the subscription in his database, then he sends the `SUBSCRIBE` message to the publisher. If the order were reversed, the following race condition would be possible: The publisher responds to the `SUBSCRIBE` message before the subscriber has stored the subscription in his database. Thus, the subscriber would respond with an `UNSUBSCRIBE` message and would proceed with storing the subscription in the database. However, the publisher would delete the subscription from its database when receiving the `UNSUBSCRIBE` message. Now, the subscriber and publisher are not synchronised: Only the subscriber has a subscription in his database.
|
|
|
|
|
|
Another potential solution to this problem was using a three-way-handshake for the subscription process. This option was rejected because of the higher messaging overhead. |
|
|
\ No newline at end of file |