3. Exigences côté client (Client-Side Requirements)
3.1. Requête (Request)
Un client enregistre son intérêt pour une ressource en émettant une requête GET avec une option Observe définie à 0 (enregistrer). Si le serveur renvoie une réponse 2.xx qui inclut également une option Observe, le serveur a ajouté avec succès une entrée avec le point de terminaison du client et le jeton de requête à la liste des observateurs de la ressource cible, et le client sera notifié des changements de l'état de la ressource.
Tout comme une réponse fraîche peut être utilisée pour satisfaire une requête sans contacter le serveur, le flux de mises à jour résultant d'une requête d'observation peut être utilisé pour satisfaire une autre requête (observation ou GET normale) si la ressource cible est la même. Un client DOIT agréger de telles requêtes et NE DOIT PAS s'enregistrer plus d'une fois pour la même ressource cible. La ressource cible est identifiée par toutes les options de la requête qui font partie de la clé de cache. Cela inclut, par exemple, l'URI complet de la requête et l'option Accept.
3.2. Notifications (Notifications)
Les notifications sont des réponses supplémentaires envoyées par le serveur en réponse à la requête GET étendue unique qui a créé l'enregistrement. Chaque notification inclut le jeton spécifié par le client dans la requête. La seule différence entre une notification et une réponse normale est la présence de l'option Observe.
Les notifications ont généralement un code de réponse 2.05 (Content). Elles incluent une option Observe avec un numéro de séquence pour la détection de réorganisation (voir la section 3.4) et une charge utile dans le même format de contenu (Content-Format) que la réponse initiale. Si le client a inclus une ou plusieurs options ETag dans la requête GET (voir la section 3.3), les notifications peuvent avoir un code de réponse 2.03 (Valid) plutôt qu'un code de réponse 2.05 (Content). De telles notifications incluent une option Observe avec un numéro de séquence mais pas de charge utile.
Dans le cas où la ressource change d'une manière qui amènerait une requête GET normale à ce moment-là à renvoyer une réponse non-2.xx (par exemple, lorsque la ressource est supprimée), le serveur envoie une notification avec un code de réponse approprié (tel que 4.04 Not Found) et supprime l'entrée du client de la liste des observateurs de la ressource. Les réponses non-2.xx n'incluent pas d'option Observe.
3.3. Mise en cache (Caching)
Comme les notifications ne sont que des réponses supplémentaires à une requête GET, les notifications participent à la mise en cache telle que définie dans la section 5.6 de la RFC 7252 [RFC7252]. Le modèle de fraîcheur et le modèle de validation sont tous deux pris en charge.
3.3.1. Fraîcheur (Freshness)
Un client PEUT stocker une notification comme une réponse dans son cache et utiliser une notification stockée qui est fraîche sans contacter le serveur. Comme une réponse, une notification est considérée comme fraîche tant que son âge n'est pas supérieur à la valeur indiquée par l'option Max-Age (et qu'aucune notification/réponse plus récente n'a été reçue).
Le serveur fera de son mieux pour maintenir l'état de la ressource observé par le client aussi étroitement synchronisé que possible avec l'état réel. Cependant, un client ne peut pas compter sur l'observation de chaque état unique qu'une ressource pourrait traverser. Par exemple, si le réseau est encombré ou si l'état change plus fréquemment que le réseau ne peut le gérer, le serveur peut sauter des notifications pour n'importe quel nombre d'états intermédiaires.
Le serveur utilise l'option Max-Age pour indiquer un âge jusqu'auquel il est acceptable que l'état observé et l'état réel soient incohérents. Si l'âge de la dernière notification devient supérieur à son Max-Age indiqué, alors le client NE DOIT PAS supposer que la représentation incluse reflète l'état réel de la ressource.
Pour s'assurer qu'il dispose d'une représentation actuelle et/ou pour réenregistrer son intérêt pour une ressource, un client PEUT émettre une nouvelle requête GET avec le même jeton que l'original à tout moment. Toutes les options DOIVENT être identiques à celles de la requête d'origine, à l'exception de l'ensemble des options ETag. Il est RECOMMANDÉ que le client n'émette pas la requête tant qu'il a encore une notification/réponse fraîche pour la ressource dans son cache. De plus, le client DEVRAIT au moins attendre un temps aléatoire entre 5 et 15 secondes après l'expiration du Max-Age pour réduire les collisions avec d'autres clients.
3.3.2. Validation (Validation)
Lorsqu'un client a une ou plusieurs notifications stockées dans son cache pour une ressource, il peut utiliser l'option ETag dans la requête GET pour donner au serveur la possibilité de sélectionner une notification stockée à utiliser.
Le client PEUT inclure une option ETag pour chaque réponse stockée qui est applicable dans la requête GET. Chaque fois que la ressource observée change pour une représentation identifiée par l'une des options ETag, le serveur peut sélectionner une réponse stockée en envoyant une notification 2.03 (Valid) avec une option ETag appropriée au lieu d'une notification 2.05 (Content).
Une implémentation client doit conserver toutes les réponses candidates dans son cache jusqu'à ce qu'elle ne soit plus intéressée par la ressource cible ou qu'elle se réenregistre avec un nouvel ensemble de balises d'entité.
3.4. Réorganisation (Reordering)
Les messages avec des notifications peuvent arriver dans un ordre différent de celui dans lequel ils ont été envoyés. Puisque l'objectif est de maintenir l'état observé aussi étroitement synchronisé que possible avec l'état réel, un client DOIT considérer la notification qui a été envoyée le plus récemment comme la plus fraîche, quel que soit l'ordre d'arrivée.
Pour fournir un ordre parmi les notifications pour le client, le serveur définit la valeur de l'option Observe dans chaque notification aux 24 bits les moins significatifs d'un numéro de séquence strictement croissant. Une notification entrante a été envoyée plus récemment que la notification la plus fraîche jusqu'à présent lorsque l'une des conditions suivantes est remplie :
(V1 < V2 et V2 - V1 < 2^23) ou
(V1 > V2 et V1 - V2 > 2^23) ou
(T2 > T1 + 128 secondes)
où V1 est la valeur de l'option Observe dans la notification la plus fraîche jusqu'à présent, V2 est la valeur de l'option Observe dans la notification entrante, T1 est un horodatage local au client pour la notification la plus fraîche jusqu'à présent, et T2 est un horodatage local au client pour la notification entrante.
Note de conception : Les deux premières conditions vérifient que V1 est inférieur à V2 dans l'arithmétique des numéros de série sur 24 bits [RFC1982]. La troisième condition garantit que si le serveur génère des numéros de série basés sur une horloge locale, le temps écoulé entre les deux messages entrants n'est pas si grand que la différence entre V1 et V2 est devenue plus grande que le plus grand entier qu'il est significatif d'ajouter à un numéro de série sur 24 bits ; en d'autres termes, après que 128 secondes se soient écoulées sans aucune notification, un client n'a pas besoin de vérifier les numéros de séquence pour supposer qu'une notification entrante a été envoyée plus récemment que la notification la plus fraîche qu'il a reçue jusqu'à présent.
La durée de 128 secondes a été choisie comme un bon nombre rond supérieur à MAX_LATENCY (Section 4.8.2 de la RFC 7252 [RFC7252]).
3.5. Transmission (Transmission)
Une notification peut être confirmable ou non confirmable, c'est-à-dire qu'elle peut être envoyée dans un message confirmable ou non confirmable. Le type de message utilisé pour une notification est indépendant du type utilisé pour la requête et de toute notification précédente.
Si un client ne reconnaît pas le jeton dans une notification confirmable, il NE DOIT PAS accuser réception du message et DEVRAIT le rejeter avec un message Reset ; sinon, le client DOIT accuser réception du message comme d'habitude. Dans le cas d'une notification non confirmable, le rejet du message avec un message Reset est OPTIONNEL.
Un message d'accusé de réception signale au serveur que le client est vivant et intéressé à recevoir d'autres notifications ; si le serveur ne reçoit pas d'accusé de réception en réponse à une notification confirmable, il supposera que le client n'est plus intéressé et supprimera finalement l'entrée associée de la liste des observateurs (Section 4.5).
3.6. Annulation (Cancellation)
Un client qui n'est plus intéressé à recevoir des notifications pour une ressource peut simplement "oublier" l'observation. Lorsque le serveur envoie ensuite la notification suivante, le client ne reconnaîtra pas le jeton dans le message et renverra donc un message Reset. Cela amène le serveur à supprimer l'entrée associée de la liste des observateurs. Les entrées dans les listes d'observateurs sont effectivement "collectées par le ramasse-miettes" par le serveur.
Note d'implémentation : En raison de la perte potentielle de messages, le message Reset peut ne pas atteindre le serveur. Le client peut donc avoir à rejeter plusieurs notifications, chacune avec un message Reset, jusqu'à ce que le serveur supprime finalement l'entrée associée de la liste des observateurs et cesse d'envoyer des notifications.
Dans certaines circonstances, il peut être souhaitable d'annuler une observation et de libérer les ressources allouées par le serveur à celle-ci plus rapidement. Dans ce cas, un client PEUT se désenregistrer explicitement en émettant une requête GET qui a le champ Token défini sur le jeton de l'observation à annuler et inclut une option Observe avec la valeur définie à 1 (désenregistrer). Toutes les autres options DOIVENT être identiques à celles de la requête d'enregistrement, à l'exception de l'ensemble des options ETag. Lorsque le serveur reçoit une telle requête, il supprimera toute entrée correspondante de la liste des observateurs et traitera la requête GET comme d'habitude.