4. Exigences côté serveur (Server-Side Requirements)
4.1. Requête (Request)
Une requête GET avec une option Observe définie à 0 (enregistrer) demande au serveur non seulement de renvoyer une représentation actuelle de la ressource cible, mais aussi d'ajouter le client à la liste des observateurs de cette ressource. En cas de succès, le serveur renvoie une représentation actuelle de la ressource et DOIT maintenir cette représentation à jour (comme décrit dans la section 1.3) tant que le client est sur la liste des observateurs.
L'entrée dans la liste des observateurs est indexée par le point de terminaison du client et le jeton spécifié par le client dans la requête. Si une entrée avec une paire point de terminaison/jeton correspondante est déjà présente dans la liste (ce qui, par exemple, se produit lorsque le client souhaite renforcer son intérêt pour une ressource), le serveur NE DOIT PAS ajouter une nouvelle entrée mais DOIT remplacer ou mettre à jour l'existante.
Un serveur qui est incapable ou ne veut pas ajouter une nouvelle entrée à la liste des observateurs d'une ressource PEUT ignorer silencieusement la requête d'enregistrement et traiter la requête GET comme d'habitude. La réponse résultante NE DOIT PAS inclure une option Observe, dont l'absence signale au client qu'il ne sera pas notifié des changements de la ressource et, par exemple, doit interroger la ressource pour son état à la place.
Si l'option Observe dans une requête GET est définie à 1 (désenregistrer), alors le serveur DOIT supprimer toute entrée existante avec une paire point de terminaison/jeton correspondante de la liste des observateurs et traiter la requête GET comme d'habitude. La réponse résultante NE DOIT PAS inclure une option Observe.
4.2. Notifications (Notifications)
Un client est notifié des changements de l'état de la ressource par des réponses supplémentaires envoyées par le serveur en réponse à la requête GET. Chaque telle réponse de notification (y compris la réponse initiale) DOIT faire écho au jeton spécifié par le client dans la requête GET. S'il y a plusieurs entrées dans la liste des observateurs, l'ordre dans lequel les clients sont notifiés n'est pas défini ; le serveur est libre d'utiliser n'importe quelle méthode pour déterminer l'ordre.
Une notification DEVRAIT avoir un code de réponse 2.05 (Content) ou 2.03 (Valid). Cependant, dans le cas où l'état d'une 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 DEVRAIT notifier le client en envoyant une notification avec un code de réponse approprié (tel que 4.04 Not Found) et DOIT ensuite supprimer l'entrée associée de la liste des observateurs de la ressource.
Le format de contenu (Content-Format) spécifié dans une notification 2.xx DOIT être le même que celui utilisé dans la réponse initiale à la requête GET. Si le serveur est incapable de continuer à envoyer des notifications dans ce format, il DEVRAIT envoyer une notification avec un code de réponse 4.06 (Not Acceptable) et DOIT ensuite supprimer l'entrée associée de la liste des observateurs de la ressource.
Une notification 2.xx DOIT inclure une option Observe avec un numéro de séquence tel que spécifié dans la section 4.4 ci-dessous ; une notification non-2.xx NE DOIT PAS inclure une option Observe.
4.3. Mise en cache (Caching)
Comme les notifications ne sont que des réponses supplémentaires envoyées par le serveur en réponse à une requête GET, elles sont soumises à la mise en cache telle que définie dans la section 5.6 de la RFC 7252 [RFC7252].
4.3.1. Fraîcheur (Freshness)
Après avoir renvoyé la réponse initiale, le serveur DOIT maintenir l'état de la ressource observé par le client aussi étroitement synchronisé que possible avec l'état réel de la ressource.
Puisqu'il est impossible d'éviter d'être parfois désynchronisé, le serveur DOIT indiquer pour chaque représentation un âge jusqu'auquel il est acceptable que l'état observé et l'état réel soient incohérents. Cet âge dépend de l'application et DOIT être spécifié dans les notifications en utilisant l'option Max-Age.
Lorsque la ressource ne change pas et que le client a une représentation actuelle, le serveur n'a pas besoin d'envoyer de notification. Cependant, si le client ne reçoit pas de notification, le client ne peut pas dire si l'état observé et l'état réel sont toujours synchronisés. Ainsi, lorsque l'âge de la dernière notification devient supérieur à son Max-Age indiqué, le client n'a plus de représentation utilisable de l'état de la ressource. Le serveur PEUT souhaiter empêcher cela en envoyant une nouvelle notification avec la représentation inchangée et un nouveau Max-Age juste avant que le Max-Age indiqué précédemment n'expire.
4.3.2. Validation (Validation)
Un client peut inclure un ensemble de balises d'entité dans sa requête en utilisant l'option ETag. Lorsqu'une ressource observée change son état et que le serveur d'origine est sur le point d'envoyer une notification 2.05 (Content), alors chaque fois que cette notification a une balise d'entité dans l'ensemble de balises d'entité spécifié par le client, le serveur PEUT envoyer une réponse 2.03 (Valid) avec une option ETag appropriée à la place.
4.4. Réorganisation (Reordering)
Parce que les messages peuvent être réorganisés, le client a besoin d'un moyen de déterminer si une notification est arrivée plus tard qu'une notification plus récente. À cette fin, le serveur DOIT définir la valeur de l'option Observe de chaque notification qu'il envoie aux 24 bits les moins significatifs d'un numéro de séquence strictement croissant. Le numéro de séquence PEUT commencer à n'importe quelle valeur et NE DOIT PAS augmenter si vite qu'il augmente de plus de 2^23 en moins de 256 secondes.
Le numéro de séquence sélectionné pour une notification DOIT être supérieur à celui de toute notification précédente envoyée au même client avec le même jeton pour la même ressource. La valeur de l'option Observe DOIT être actuelle au moment de la transmission ; si une notification est retransmise, le serveur DOIT mettre à jour la valeur de l'option au numéro de séquence qui est actuel à ce moment-là avant la retransmission.
Note d'implémentation : Une implémentation simple qui satisfait aux exigences consiste à obtenir un horodatage à partir d'une horloge locale. Le numéro de séquence est alors l'horodatage en tics, où 1 tic = (256 secondes)/(2^23) = 30,52 microsecondes. Il n'est pas nécessaire que l'horloge reflète l'heure/la date actuelle.
Une autre implémentation valide consiste à stocker une variable entière non signée de 24 bits par ressource et à incrémenter cette variable chaque fois que la ressource subit un changement d'état (à condition que la ressource change son état moins de 2^23 fois dans les 256 premières secondes après chaque changement d'état). Cela supprime le besoin de mettre à jour la valeur de l'option Observe lors de la retransmission lorsque l'état de la ressource n'a pas changé.
Note de conception : Le choix d'une valeur d'option de 24 bits et d'une durée de 256 secondes permet théoriquement un taux de notification allant jusqu'à 65536 notifications par seconde. Les nœuds contraints ont souvent des horloges plutôt imprécises, cependant, et les inexactitudes du côté client et serveur peuvent s'annuler ou s'ajouter en effet. Par conséquent, le taux de notification maximal est réduit à 32768 notifications par seconde. C'est encore bien au-delà de l'objectif de conception connu le plus élevé d'environ 1 kHz (la plupart des applications CoAP seront de plusieurs ordres de grandeur en dessous de cela) mais permet des inexactitudes d'horloge totales allant jusqu'à -50/+100%.
4.5. Transmission (Transmission)
Une notification peut être envoyée dans un message confirmable ou non confirmable. Le type de message utilisé dépend généralement de l'application et peut être déterminé par le serveur pour chaque notification individuellement.
Par exemple, pour les ressources qui changent de manière quelque peu prévisible ou régulière, les notifications peuvent être envoyées dans des messages non confirmables ; pour les ressources qui changent rarement, les notifications peuvent être envoyées dans des messages confirmables. Le serveur peut combiner ces deux approches en fonction de la fréquence des changements d'état et de l'importance des notifications individuelles.
Un serveur PEUT choisir de sauter l'envoi d'une notification s'il sait qu'il enverra bientôt une autre notification, par exemple, lorsque l'état d'une ressource change fréquemment. Il PEUT également choisir d'envoyer plus d'une notification pour le même état de ressource. Cependant, par-dessus tout, le serveur DOIT s'assurer qu'un client dans la liste des observateurs d'une ressource observe finalement le dernier état si la ressource ne subit pas de nouveau changement d'état.
Par exemple, lorsque des changements d'état se produisent par rafales, le serveur peut sauter certaines notifications, envoyer les notifications dans des messages non confirmables, et s'assurer que le client observe le dernier changement d'état en répétant la dernière notification dans un message confirmable lorsque la rafale est terminée.
L'accusé de réception du client d'une notification confirmable signale que le client est intéressé à recevoir d'autres notifications. Si un client rejette une notification confirmable ou non confirmable avec un message Reset, ou si la dernière tentative de retransmission d'une notification confirmable expire, alors le client est considéré comme n'étant plus intéressé et le serveur DOIT supprimer l'entrée associée de la liste des observateurs.
Note d'implémentation : Pour traiter correctement un message Reset qui rejette une notification non confirmable, un serveur doit se souvenir des ID de message des notifications non confirmables qu'il envoie. Cela peut être difficile pour un serveur avec des ressources contraintes. Cependant, comme les messages Reset sont transmis de manière non fiable, le client doit être préparé au cas où les messages Reset ne seraient pas reçus par le serveur. Ainsi, un serveur peut toujours prétendre qu'un message Reset rejetant une notification non confirmable a été perdu.
Si un serveur fait cela, il pourrait accélérer l'annulation en envoyant les notifications suivantes à ce client dans des messages confirmables.
Un serveur qui transmet des notifications principalement dans des messages non confirmables DOIT envoyer une notification dans un message confirmable au lieu d'un message non confirmable au moins toutes les 24 heures. Cela empêche un client qui est parti ou n'est plus intéressé de rester indéfiniment dans la liste des observateurs.
4.5.1. Contrôle de congestion (Congestion Control)
Le contrôle de congestion de base pour CoAP est fourni par le mécanisme de recul exponentiel de la section 4.2 de la RFC 7252 [RFC7252] et les limitations de la section 4.7 de la RFC 7252 [RFC7252]. Cependant, CoAP place la responsabilité du contrôle de congestion pour les interactions simples requête/réponse uniquement sur les clients : la limitation du débit de transmission des requêtes contrôle implicitement la transmission des réponses. Lorsqu'une seule requête produit un nombre potentiellement infini de notifications, une responsabilité supplémentaire doit être placée sur le serveur.
Afin de ne pas provoquer de congestion, les serveurs DOIVENT limiter strictement le nombre de notifications/réponses en attente simultanées qu'ils transmettent à un client donné à NSTART (1 par défaut ; voir la section 4.7 de la RFC 7252 [RFC7252]). Une notification/réponse en attente est soit un message confirmable pour lequel un accusé de réception n'a pas encore été reçu et dont la dernière tentative de retransmission n'a pas encore expiré, soit un message non confirmable pour lequel le temps d'attente résultant des règles de limitation de débit suivantes ne s'est pas encore écoulé.
Le serveur NE DEVRAIT PAS envoyer plus d'une notification non confirmable par temps d'aller-retour (RTT) à un client en moyenne. Si le serveur ne peut pas maintenir une estimation RTT pour un client, il NE DEVRAIT PAS envoyer plus d'une notification non confirmable toutes les 3 secondes et DEVRAIT utiliser un taux encore moins agressif lorsque cela est possible (voir aussi la section 3.1.2 de la RFC 5405 [RFC5405]).
D'autres optimisations et considérations de contrôle de congestion sont attendues à l'avenir avec des mécanismes de contrôle de congestion CoAP avancés.
4.5.2. Transmission avancée (Advanced Transmission)
L'état d'une ressource observée peut changer alors que le nombre de notifications/réponses en attente simultanées à un client sur la liste des observateurs est supérieur ou égal à NSTART. Dans ce cas, le serveur ne peut pas notifier le client du nouvel état de la ressource immédiatement mais doit attendre qu'une notification/réponse en attente soit terminée d'abord.
S'il existe une notification/réponse en attente que le serveur transmet au client et qui concerne la ressource modifiée, alors il est souhaitable que le serveur cesse de travailler pour obtenir la représentation de l'ancien état de la ressource pour le client et commence à transmettre la représentation actuelle au client à la place, afin que l'état de la ressource observé par le client reste plus étroitement synchronisé avec l'état réel sur le serveur.
À cette fin, le serveur PEUT optimiser le processus de transmission en abandonnant la transmission de l'ancienne notification (mais pas avant que la tentative de transmission actuelle ne soit terminée) et en commençant une nouvelle transmission pour la nouvelle notification (mais avec le minuteur de retransmission et le compteur de la transmission abandonnée conservés).
Plus en détail, un serveur PEUT remplacer une transmission en attente qui concerne une observation comme suit :