Passa al contenuto principale

1. Introduzione

1.1. Contesto

Il Constrained Application Protocol (CoAP) [RFC7252] è destinato a fornire servizi RESTful [REST] non dissimili da HTTP [RFC7230] riducendo al contempo la complessità dell'implementazione e la dimensione dei pacchetti scambiati al fine di rendere questi servizi utili in una rete altamente vincolata di nodi a loro volta altamente vincolati [RFC7228].

Il modello di REST è quello di un client che scambia rappresentazioni di risorse con un server, dove una rappresentazione cattura lo stato attuale o previsto di una risorsa. Il server è l'autorità per le rappresentazioni delle risorse nel suo spazio dei nomi. Un client interessato allo stato di una risorsa avvia una richiesta al server; il server restituisce quindi una risposta con una rappresentazione della risorsa che è attuale al momento della richiesta.

Questo modello non funziona bene quando un client è interessato ad avere una rappresentazione attuale di una risorsa per un periodo di tempo. Gli approcci esistenti da HTTP, come il polling ripetuto o l'HTTP long polling [RFC6202], generano una complessità e/o un overhead significativi e quindi sono meno applicabili in un ambiente vincolato.

Il protocollo specificato in questo documento estende il protocollo core CoAP con un meccanismo per un client CoAP per "osservare" una risorsa su un server CoAP: il client recupera una rappresentazione della risorsa e richiede che questa rappresentazione sia aggiornata dal server finché il client è interessato alla risorsa.

Il protocollo mantiene le proprietà architetturali di REST. Consente un'elevata scalabilità ed efficienza attraverso il supporto di cache e proxy. Non c'è intenzione, tuttavia, di risolvere l'intero set di problemi che le soluzioni HTTP esistenti risolvono o di sostituire le reti publish/subscribe che risolvono un problema molto più generale [RFC5989].

1.2. Panoramica del protocollo

Il protocollo si basa sul noto design pattern observer [GOF]. In questo design pattern, i componenti chiamati "osservatori" si registrano presso uno specifico, noto provider chiamato "soggetto" per essere notificati ogni volta che il soggetto subisce un cambiamento di stato. Il soggetto è responsabile dell'amministrazione del suo elenco di osservatori registrati. Se più soggetti sono di interesse per un osservatore, l'osservatore deve registrarsi separatamente per tutti loro.

                       Osservatore          Soggetto
| |
| Registrazione |
+------------------->|
| |
| Notifica |
|<-------------------+
| |
| Notifica |
|<-------------------+
| |
| Notifica |
|<-------------------+
| |

Figura 1: Il Design Pattern Observer

Il design pattern observer è realizzato in CoAP come segue:

Soggetto: Nel contesto di CoAP, il soggetto è una risorsa nello spazio dei nomi di un server CoAP. Lo stato della risorsa può cambiare nel tempo, variando da aggiornamenti infrequenti a trasformazioni di stato continue.

Osservatore: Un osservatore è un client CoAP che è interessato ad avere una rappresentazione attuale della risorsa in qualsiasi momento.

Registrazione: Un client registra il suo interesse in una risorsa avviando una richiesta GET estesa al server. Oltre a restituire una rappresentazione della risorsa di destinazione, questa richiesta fa sì che il server aggiunga il client all'elenco degli osservatori della risorsa.

Notifica: Ogni volta che lo stato di una risorsa cambia, il server notifica ogni client nell'elenco degli osservatori della risorsa. Ogni notifica è una risposta CoAP aggiuntiva inviata dal server in risposta alla singola richiesta GET estesa e include una rappresentazione completa e aggiornata del nuovo stato della risorsa.

La Figura 2 di seguito mostra un esempio di un client CoAP che registra il suo interesse in una risorsa e riceve tre notifiche: la prima con lo stato attuale al momento della registrazione, e poi due al momento dei cambiamenti dello stato della risorsa. Sia la richiesta di registrazione che le notifiche sono identificate come tali dalla presenza dell'Opzione Observe definita in questo documento. Nelle notifiche, l'Opzione Observe fornisce inoltre un numero di sequenza per il rilevamento del riordino. Tutte le notifiche portano il token specificato dal client, in modo che il client possa facilmente correlarle alla richiesta.

                       Client                Server
| |
| GET /temperature |
| Token: 0x4a | Registrazione
| Observe: 0 |
+------------------->|
| |
| 2.05 Content |
| Token: 0x4a | Notifica dello
| Observe: 12 | stato attuale
| Payload: 22.9 Cel |
|<-------------------+
| |
| 2.05 Content |
| Token: 0x4a | Notifica a seguito
| Observe: 44 | di un cambio di
| Payload: 22.8 Cel | stato
|<-------------------+
| |
| 2.05 Content |
| Token: 0x4a | Notifica a seguito
| Observe: 60 | di un cambio di
| Payload: 23.1 Cel | stato
|<-------------------+
| |

Figura 2: Osservazione di una risorsa in CoAP

Nota: In questo documento, "Cel" sta per "gradi Celsius".

Un client rimane nell'elenco degli osservatori finché il server può determinare l'interesse continuo del client per la risorsa. Il server può inviare una notifica in un messaggio CoAP confermabile per richiedere un riconoscimento dal client. Quando il client si cancella, rifiuta una notifica, o la trasmissione di una notifica scade dopo diversi tentativi di trasmissione, il client è considerato non più interessato alla risorsa e viene rimosso dal server dall'elenco degli osservatori.

1.3. Modello di coerenza

Mentre un client è nell'elenco degli osservatori di una risorsa, l'obiettivo del protocollo è mantenere lo stato della risorsa osservato dal client il più strettamente sincronizzato possibile con lo stato effettivo sul server.

Non si può evitare che il client e il server diventino non sincronizzati a volte: Primo, c'è sempre una certa latenza tra il cambiamento dello stato della risorsa e la ricezione della notifica. Secondo, i messaggi CoAP con le notifiche possono andare persi, il che farà sì che il client assuma un vecchio stato finché non riceve una nuova notifica. E terzo, il server può erroneamente giungere alla conclusione che il client non è più interessato alla risorsa, il che farà sì che il server smetta di inviare notifiche e il client assuma un vecchio stato finché non registra eventualmente di nuovo il suo interesse.

Il protocollo affronta questo problema come segue:

  • Segue un approccio best-effort per l'invio della rappresentazione attuale al client dopo un cambiamento di stato: i client dovrebbero vedere il nuovo stato dopo un cambiamento di stato il prima possibile, e dovrebbero vedere quanti più stati possibile. Questo è limitato dal controllo della congestione, tuttavia, quindi un client non può contare sull'osservazione di ogni singolo stato che una risorsa potrebbe attraversare.

  • Etichetta le notifiche con una durata massima fino alla quale è accettabile che lo stato osservato e lo stato effettivo non siano sincronizzati. Quando l'età della notifica ricevuta raggiunge questo limite, il client non può utilizzare la rappresentazione inclusa finché non riceve una nuova notifica.

  • È progettato sul principio della coerenza eventuale: il protocollo garantisce che se la risorsa non subisce un nuovo cambiamento di stato, alla fine tutti gli osservatori registrati avranno una rappresentazione attuale dell'ultimo stato della risorsa.

1.4. Risorse osservabili

Un server CoAP è l'autorità per determinare in quali condizioni le risorse cambiano il loro stato e quindi quando gli osservatori vengono notificati dei nuovi stati delle risorse. Il protocollo non offre mezzi espliciti per impostare trigger o soglie; spetta al server esporre risorse osservabili che cambiano il loro stato in un modo utile nel contesto dell'applicazione.

Ad esempio, un server CoAP con un sensore di temperatura collegato potrebbe esporre una o più delle seguenti risorse:

  • <coap://server/temperature>, che cambia il suo stato ogni pochi secondi a una lettura attuale del sensore di temperatura;

  • <coap://server/temperature/felt>, che cambia il suo stato a "COLD" ogni volta che la lettura della temperatura scende al di sotto di una certa soglia preconfigurata e a "WARM" ogni volta che la lettura supera una seconda soglia leggermente più alta;

  • <coap://server/temperature/critical?above=42>, che cambia il suo stato in base al valore del parametro specificato dal client o ogni pochi secondi alla lettura attuale della temperatura se la temperatura supera la soglia o a "OK" quando la lettura scende al di sotto;

  • <coap://server/?query=select+avg(temperature)+from+Sensor.window:time(30sec)>, che accetta espressioni di complessità arbitraria e cambia il suo stato di conseguenza.

Pertanto, progettando risorse CoAP che cambiano il loro stato in determinate condizioni, è possibile aggiornare il client solo quando si verificano queste condizioni invece di fornirgli continuamente dati grezzi del sensore. Parametrizzando le risorse, questo non è limitato alle condizioni definite dal server, ma può essere esteso a query arbitrariamente complesse specificate dal client. Il progettista dell'applicazione può quindi scegliere esattamente il giusto livello di complessità per l'applicazione prevista e i dispositivi coinvolti e non è vincolato a un meccanismo "taglia unica" integrato nel protocollo.

1.5. Notazione dei requisiti

Le parole chiave "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" e "OPTIONAL" in questo documento devono essere interpretate come descritto in RFC 2119 [RFC2119].