Zum Hauptinhalt springen

4. Serverseitige Anforderungen (Server-Side Requirements)

4.1. Anfrage (Request)

Eine GET-Anfrage mit einer auf 0 (registrieren) gesetzten Observe-Option fordert den Server nicht nur auf, eine aktuelle Repräsentation der Zielressource zurückzugeben, sondern auch den Client zur Liste der Beobachter dieser Ressource hinzuzufügen. Bei Erfolg gibt der Server eine aktuelle Repräsentation der Ressource zurück und MUSS diese Repräsentation aktualisiert halten (wie in Abschnitt 1.3 beschrieben), solange der Client auf der Liste der Beobachter steht.

Der Eintrag in der Liste der Beobachter wird durch den Client-Endpunkt und das vom Client in der Anfrage angegebene Token identifiziert. Wenn bereits ein Eintrag mit einem passenden Endpunkt/Token-Paar in der Liste vorhanden ist (was zum Beispiel passiert, wenn der Client sein Interesse an einer Ressource bekräftigen möchte), DARF der Server KEINEN neuen Eintrag hinzufügen, sondern MUSS den vorhandenen ersetzen oder aktualisieren.

Ein Server, der nicht in der Lage oder nicht willens ist, einen neuen Eintrag zur Liste der Beobachter einer Ressource hinzuzufügen, KANN die Registrierungsanfrage stillschweigend ignorieren und die GET-Anfrage wie üblich verarbeiten. Die resultierende Antwort DARF KEINE Observe-Option enthalten, deren Fehlen dem Client signalisiert, dass er nicht über Änderungen der Ressource benachrichtigt wird und z. B. stattdessen die Ressource nach ihrem Zustand abfragen muss.

Wenn die Observe-Option in einer GET-Anfrage auf 1 (abmelden) gesetzt ist, dann MUSS der Server jeden vorhandenen Eintrag mit einem passenden Endpunkt/Token-Paar aus der Liste der Beobachter entfernen und die GET-Anfrage wie üblich verarbeiten. Die resultierende Antwort DARF KEINE Observe-Option enthalten.

4.2. Benachrichtigungen (Notifications)

Ein Client wird über Änderungen des Ressourcenzustands durch zusätzliche Antworten benachrichtigt, die vom Server als Antwort auf die GET-Anfrage gesendet werden. Jede solche Benachrichtigungsantwort (einschließlich der ursprünglichen Antwort) MUSS das vom Client in der GET-Anfrage angegebene Token wiedergeben. Wenn es mehrere Einträge in der Liste der Beobachter gibt, ist die Reihenfolge, in der die Clients benachrichtigt werden, nicht definiert; dem Server steht es frei, jede Methode zur Bestimmung der Reihenfolge zu verwenden.

Eine Benachrichtigung SOLLTE einen 2.05 (Content) oder 2.03 (Valid) Antwortcode haben. Für den Fall jedoch, dass sich der Zustand einer Ressource auf eine Weise ändert, die dazu führen würde, dass eine normale GET-Anfrage zu diesem Zeitpunkt eine Nicht-2.xx-Antwort zurückgibt (zum Beispiel, wenn die Ressource gelöscht wird), SOLLTE der Server den Client benachrichtigen, indem er eine Benachrichtigung mit einem entsprechenden Antwortcode (wie 4.04 Not Found) sendet, und MUSS anschließend den zugehörigen Eintrag aus der Liste der Beobachter der Ressource entfernen.

Das in einer 2.xx-Benachrichtigung angegebene Content-Format MUSS dasselbe sein wie das in der ursprünglichen Antwort auf die GET-Anfrage verwendete. Wenn der Server nicht in der Lage ist, weiterhin Benachrichtigungen in diesem Format zu senden, SOLLTE er eine Benachrichtigung mit einem 4.06 (Not Acceptable) Antwortcode senden und MUSS anschließend den zugehörigen Eintrag aus der Liste der Beobachter der Ressource entfernen.

Eine 2.xx-Benachrichtigung MUSS eine Observe-Option mit einer Sequenznummer enthalten, wie in Abschnitt 4.4 unten spezifiziert; eine Nicht-2.xx-Benachrichtigung DARF KEINE Observe-Option enthalten.

4.3. Caching

Da Benachrichtigungen nur zusätzliche Antworten sind, die vom Server als Antwort auf eine GET-Anfrage gesendet werden, unterliegen sie dem Caching, wie in Abschnitt 5.6 von RFC 7252 [RFC7252] definiert.

4.3.1. Frische (Freshness)

Nach Rückgabe der ursprünglichen Antwort MUSS der Server den vom Client beobachteten Ressourcenzustand so eng wie möglich mit dem tatsächlichen Ressourcenzustand synchron halten.

Da es sich nicht vermeiden lässt, zeitweise nicht synchron zu sein, MUSS der Server für jede Repräsentation ein Alter angeben, bis zu dem es akzeptabel ist, dass der beobachtete Zustand und der tatsächliche Zustand inkonsistent sind. Dieses Alter ist anwendungsabhängig und MUSS in Benachrichtigungen unter Verwendung der Max-Age-Option angegeben werden.

Wenn sich die Ressource nicht ändert und der Client eine aktuelle Repräsentation hat, muss der Server keine Benachrichtigung senden. Wenn der Client jedoch keine Benachrichtigung erhält, kann der Client nicht feststellen, ob der beobachtete Zustand und der tatsächliche Zustand noch synchron sind. Wenn also das Alter der neuesten Benachrichtigung größer wird als ihr angegebenes Max-Age, hat der Client keine verwendbare Repräsentation des Ressourcenzustands mehr. Der Server KANN dies verhindern wollen, indem er kurz vor Ablauf des zuvor angegebenen Max-Age eine neue Benachrichtigung mit der unveränderten Repräsentation und einem neuen Max-Age sendet.

4.3.2. Validierung (Validation)

Ein Client kann einen Satz von Entity-Tags unter Verwendung der ETag-Option in seine Anfrage aufnehmen. Wenn eine beobachtete Ressource ihren Zustand ändert und der Ursprungsserver dabei ist, eine 2.05 (Content) Benachrichtigung zu senden, dann KANN der Server, wann immer diese Benachrichtigung ein Entity-Tag im vom Client angegebenen Satz von Entity-Tags hat, stattdessen eine 2.03 (Valid) Antwort mit einer entsprechenden ETag-Option senden.

4.4. Umordnung (Reordering)

Da Nachrichten umgeordnet werden können, benötigt der Client einen Weg, um festzustellen, ob eine Benachrichtigung später als eine neuere Benachrichtigung eingetroffen ist. Zu diesem Zweck MUSS der Server den Wert der Observe-Option jeder von ihm gesendeten Benachrichtigung auf die 24 niedrigstwertigen Bits einer streng monoton steigenden Sequenznummer setzen. Die Sequenznummer KANN bei einem beliebigen Wert beginnen und DARF NICHT so schnell ansteigen, dass sie innerhalb von weniger als 256 Sekunden um mehr als 2^23 ansteigt.

Die für eine Benachrichtigung ausgewählte Sequenznummer MUSS größer sein als die jeder vorhergehenden Benachrichtigung, die an denselben Client mit demselben Token für dieselbe Ressource gesendet wurde. Der Wert der Observe-Option MUSS zum Zeitpunkt der Übertragung aktuell sein; wenn eine Benachrichtigung erneut übertragen wird, MUSS der Server den Wert der Option vor der erneuten Übertragung auf die zu diesem Zeitpunkt aktuelle Sequenznummer aktualisieren.

Implementierungshinweis: Eine einfache Implementierung, die die Anforderungen erfüllt, besteht darin, einen Zeitstempel von einer lokalen Uhr zu erhalten. Die Sequenznummer ist dann der Zeitstempel in Ticks, wobei 1 Tick = (256 Sekunden)/(2^23) = 30,52 Mikrosekunden ist. Es ist nicht erforderlich, dass die Uhr die aktuelle Zeit/das aktuelle Datum widerspiegelt.

Eine weitere gültige Implementierung besteht darin, eine 24-Bit-vorzeichenlose Ganzzahlvariable pro Ressource zu speichern und diese Variable jedes Mal zu inkrementieren, wenn die Ressource eine Zustandsänderung erfährt (vorausgesetzt, dass die Ressource ihren Zustand weniger als 2^23 Mal in den ersten 256 Sekunden nach jeder Zustandsänderung ändert). Dies beseitigt die Notwendigkeit, den Wert der Observe-Option bei erneuter Übertragung zu aktualisieren, wenn sich der Ressourcenzustand nicht geändert hat.

Design-Hinweis: Die Wahl eines 24-Bit-Optionswerts und einer Zeitspanne von 256 Sekunden ermöglicht theoretisch eine Benachrichtigungsrate von bis zu 65536 Benachrichtigungen pro Sekunde. Eingeschränkte Knoten haben jedoch oft ziemlich ungenaue Uhren, und Ungenauigkeiten auf Client- und Server-Seite können sich aufheben oder in ihrer Wirkung addieren. Daher wird die maximale Benachrichtigungsrate auf 32768 Benachrichtigungen pro Sekunde reduziert. Dies liegt immer noch weit über dem höchsten bekannten Designziel von etwa 1 kHz (die meisten CoAP-Anwendungen werden mehrere Größenordnungen darunter liegen), erlaubt aber gesamte Uhrungenauigkeiten von bis zu -50/+100%.

4.5. Übertragung (Transmission)

Eine Benachrichtigung kann in einer bestätigbaren oder einer nicht bestätigbaren Nachricht gesendet werden. Der verwendete Nachrichtentyp ist typischerweise anwendungsabhängig und kann vom Server für jede Benachrichtigung individuell bestimmt werden.

Zum Beispiel können für Ressourcen, die sich auf eine etwas vorhersehbare oder regelmäßige Weise ändern, Benachrichtigungen in nicht bestätigbaren Nachrichten gesendet werden; für Ressourcen, die sich selten ändern, können Benachrichtigungen in bestätigbaren Nachrichten gesendet werden. Der Server kann diese beiden Ansätze abhängig von der Häufigkeit von Zustandsänderungen und der Wichtigkeit einzelner Benachrichtigungen kombinieren.

Ein Server KANN sich entscheiden, das Senden einer Benachrichtigung zu überspringen, wenn er weiß, dass er bald eine weitere Benachrichtigung senden wird, zum Beispiel, wenn sich der Zustand einer Ressource häufig ändert. Er KANN sich auch entscheiden, mehr als eine Benachrichtigung für denselben Ressourcenzustand zu senden. Vor allem MUSS der Server jedoch sicherstellen, dass ein Client in der Liste der Beobachter einer Ressource schließlich den neuesten Zustand beobachtet, wenn die Ressource keine neue Zustandsänderung erfährt.

Wenn zum Beispiel Zustandsänderungen in Bursts auftreten, kann der Server einige Benachrichtigungen überspringen, die Benachrichtigungen in nicht bestätigbaren Nachrichten senden und sicherstellen, dass der Client die neueste Zustandsänderung beobachtet, indem er die letzte Benachrichtigung in einer bestätigbaren Nachricht wiederholt, wenn der Burst vorbei ist.

Die Bestätigung einer bestätigbaren Benachrichtigung durch den Client signalisiert, dass der Client daran interessiert ist, weitere Benachrichtigungen zu erhalten. Wenn ein Client eine bestätigbare oder nicht bestätigbare Benachrichtigung mit einer Reset-Nachricht ablehnt oder wenn der letzte Versuch, eine bestätigbare Benachrichtigung erneut zu übertragen, eine Zeitüberschreitung aufweist, dann wird der Client als nicht mehr interessiert betrachtet und der Server MUSS den zugehörigen Eintrag aus der Liste der Beobachter entfernen.

Implementierungshinweis: Um eine Reset-Nachricht, die eine nicht bestätigbare Benachrichtigung ablehnt, ordnungsgemäß zu verarbeiten, muss sich ein Server die Nachrichten-IDs der von ihm gesendeten nicht bestätigbaren Benachrichtigungen merken. Dies kann für einen Server mit eingeschränkten Ressourcen eine Herausforderung sein. Da Reset-Nachrichten jedoch unzuverlässig übertragen werden, muss der Client für den Fall vorbereitet sein, dass die Reset-Nachrichten nicht vom Server empfangen werden. Somit kann ein Server immer so tun, als ob eine Reset-Nachricht, die eine nicht bestätigbare Benachrichtigung ablehnt, verloren gegangen wäre.

Wenn ein Server dies tut, könnte er die Stornierung beschleunigen, indem er die folgenden Benachrichtigungen an diesen Client in bestätigbaren Nachrichten sendet.

Ein Server, der Benachrichtigungen hauptsächlich in nicht bestätigbaren Nachrichten überträgt, MUSS mindestens alle 24 Stunden eine Benachrichtigung in einer bestätigbaren Nachricht anstelle einer nicht bestätigbaren Nachricht senden. Dies verhindert, dass ein Client, der verschwunden ist oder nicht mehr interessiert ist, auf unbestimmte Zeit in der Liste der Beobachter verbleibt.

4.5.1. Überlastungskontrolle (Congestion Control)

Grundlegende Überlastungskontrolle für CoAP wird durch den exponentiellen Back-off-Mechanismus in Abschnitt 4.2 von RFC 7252 [RFC7252] und die Einschränkungen in Abschnitt 4.7 von RFC 7252 [RFC7252] bereitgestellt. CoAP legt jedoch die Verantwortung für die Überlastungskontrolle für einfache Anfrage/Antwort-Interaktionen nur auf die Clients: Die ratenbegrenzende Anfrageübertragung steuert implizit die Übertragung der Antworten. Wenn eine einzelne Anfrage eine potenziell unendliche Anzahl von Benachrichtigungen ergibt, muss dem Server zusätzliche Verantwortung übertragen werden.

Um keine Überlastung zu verursachen, MÜSSEN Server die Anzahl der gleichzeitigen ausstehenden Benachrichtigungen/Antworten, die sie an einen bestimmten Client übertragen, strikt auf NSTART begrenzen (standardmäßig 1; siehe Abschnitt 4.7 von RFC 7252 [RFC7252]). Eine ausstehende Benachrichtigung/Antwort ist entweder eine bestätigbare Nachricht, für die noch keine Bestätigung empfangen wurde und deren letzter Neuübertragungsversuch noch keine Zeitüberschreitung aufwies, oder eine nicht bestätigbare Nachricht, für die die Wartezeit, die aus den folgenden Ratenbegrenzungsregeln resultiert, noch nicht abgelaufen ist.

Der Server SOLLTE im Durchschnitt NICHT mehr als eine nicht bestätigbare Benachrichtigung pro Round-Trip-Zeit (RTT) an einen Client senden. Wenn der Server keine RTT-Schätzung für einen Client aufrechterhalten kann, SOLLTE er NICHT mehr als eine nicht bestätigbare Benachrichtigung alle 3 Sekunden senden und SOLLTE eine noch weniger aggressive Rate verwenden, wenn möglich (siehe auch Abschnitt 3.1.2 von RFC 5405 [RFC5405]).

Weitere Optimierungen und Überlegungen zur Überlastungskontrolle werden in Zukunft mit fortschrittlichen CoAP-Überlastungskontrollmechanismen erwartet.

4.5.2. Erweiterte Übertragung (Advanced Transmission)

Der Zustand einer beobachteten Ressource kann sich ändern, während die Anzahl der gleichzeitigen ausstehenden Benachrichtigungen/Antworten an einen Client auf der Liste der Beobachter größer oder gleich NSTART ist. In diesem Fall kann der Server den Client nicht sofort über den neuen Ressourcenzustand benachrichtigen, sondern muss warten, bis eine ausstehende Benachrichtigung/Antwort zuerst abgeschlossen ist.

Wenn eine ausstehende Benachrichtigung/Antwort existiert, die der Server an den Client überträgt und die sich auf die geänderte Ressource bezieht, dann ist es wünschenswert, dass der Server aufhört, daran zu arbeiten, die Repräsentation des alten Ressourcenzustands an den Client zu bringen, und stattdessen beginnt, die aktuelle Repräsentation an den Client zu übertragen, damit der vom Client beobachtete Ressourcenzustand enger mit dem tatsächlichen Zustand auf dem Server synchron bleibt.

Zu diesem Zweck KANN der Server den Übertragungsprozess optimieren, indem er die Übertragung der alten Benachrichtigung abbricht (aber nicht bevor der aktuelle Übertragungsversuch abgeschlossen ist) und eine neue Übertragung für die neue Benachrichtigung beginnt (aber mit beibehaltenem Neuübertragungstimer und Zähler der abgebrochenen Übertragung).

Genauer gesagt KANN ein Server eine ausstehende Übertragung, die sich auf eine Beobachtung bezieht, wie folgt ersetzen: