Zum Hauptinhalt springen

3. Beispiele

Dieser Abschnitt enthält eine Reihe kurzer Beispiele mit Nachrichtenflüssen für ein blockweises GET und für ein PUT oder POST. Diese Beispiele demonstrieren den grundlegenden Betrieb, den Betrieb bei Vorhandensein von erneuten Übertragungen und Beispiele für den Betrieb der Blockgrößenverhandlung.

In all diesen Beispielen wird eine Block-Option auf zerlegte Weise angezeigt, die die Art der Block-Option (1 oder 2) gefolgt von einem Doppelpunkt angibt, und dann die Blocknummer (NUM), das More-Bit (M) und den Blockgrößenexponenten (2**(SZX+4)) getrennt durch Schrägstriche. Beispielsweise würde ein Block2-Optionswert von 33 als 2:2/0/32 angezeigt und ein Block1-Optionswert von 59 würde als 1:3/1/128 angezeigt.

Wie in [RFC7252] wird "MID" als Abkürzung für "Message ID" (Nachrichten-ID) verwendet.

3.1. Block2-Beispiele

Das erste Beispiel (Abbildung 2) zeigt eine GET-Anfrage, die in drei Blöcke aufgeteilt ist. Der Server schlägt eine Blockgröße von 128 vor, und der Client stimmt zu. Die ersten beiden ACKs enthalten jeweils eine Nutzlast von 128 Bytes, und das dritte ACK enthält eine Nutzlast zwischen 1 und 128 Bytes.

CLIENT                                                     SERVER
| |
| CON [MID=1234], GET, /status ------> |
| |
| <------ ACK [MID=1234], 2.05 Content, 2:0/1/128 |
| |
| CON [MID=1235], GET, /status, 2:1/0/128 ------> |
| |
| <------ ACK [MID=1235], 2.05 Content, 2:1/1/128 |
| |
| CON [MID=1236], GET, /status, 2:2/0/128 ------> |
| |
| <------ ACK [MID=1236], 2.05 Content, 2:2/0/128 |

Abbildung 2: Einfaches blockweises GET

Im zweiten Beispiel (Abbildung 3) antizipiert der Client die blockweise Übertragung (z. B. aufgrund einer Größenangabe in der Link-Format-Beschreibung [RFC6690]) und sendet einen Blockgrößenvorschlag. Alle ACK-Nachrichten mit Ausnahme der letzten tragen 64 Bytes Nutzlast; die letzte trägt zwischen 1 und 64 Bytes.

CLIENT                                                     SERVER
| |
| CON [MID=1234], GET, /status, 2:0/0/64 ------> |
| |
| <------ ACK [MID=1234], 2.05 Content, 2:0/1/64 |
| |
| CON [MID=1235], GET, /status, 2:1/0/64 ------> |
| |
| <------ ACK [MID=1235], 2.05 Content, 2:1/1/64 |
: :
: ... :
: :
| CON [MID=1238], GET, /status, 2:4/0/64 ------> |
| |
| <------ ACK [MID=1238], 2.05 Content, 2:4/1/64 |
| |
| CON [MID=1239], GET, /status, 2:5/0/64 ------> |
| |
| <------ ACK [MID=1239], 2.05 Content, 2:5/0/64 |

Abbildung 3: Blockweises GET mit früher Verhandlung

Im dritten Beispiel (Abbildung 4) ist der Client überrascht von der Notwendigkeit einer blockweisen Übertragung und unzufrieden mit der vom Server einseitig gewählten Größe. Da er ursprünglich keinen Größenvorschlag gesendet hat, beeinflusst die Verhandlung die Größe erst ab dem zweiten Nachrichtenaustausch. Da der Client bereits sowohl den ersten als auch den zweiten 64-Byte-Block im ersten 128-Byte-Austausch erhalten hat, fordert er weiterhin den dritten 64-Byte-Block an ("2/0/64"). Nichts davon wird (oder muss) vom Server verstanden werden, der einfach so gut er kann auf die Anfragen antwortet.

CLIENT                                                     SERVER
| |
| CON [MID=1234], GET, /status ------> |
| |
| <------ ACK [MID=1234], 2.05 Content, 2:0/1/128 |
| |
| CON [MID=1235], GET, /status, 2:2/0/64 ------> |
| |
| <------ ACK [MID=1235], 2.05 Content, 2:2/1/64 |
| |
| CON [MID=1236], GET, /status, 2:3/0/64 ------> |
| |
| <------ ACK [MID=1236], 2.05 Content, 2:3/1/64 |
| |
| CON [MID=1237], GET, /status, 2:4/0/64 ------> |
| |
| <------ ACK [MID=1237], 2.05 Content, 2:4/1/64 |
| |
| CON [MID=1238], GET, /status, 2:5/0/64 ------> |
| |
| <------ ACK [MID=1238], 2.05 Content, 2:5/0/64 |

Abbildung 4: Blockweises GET mit später Verhandlung

In all diesen (und den folgenden) Fällen werden erneute Übertragungen von der CoAP-Nachrichtenaustauschschicht behandelt, sodass sie die Blockoperationen nicht beeinflussen (Abbildungen 5 und 6).

CLIENT                                                     SERVER
| |
| CON [MID=1234], GET, /status ------> |
| |
| <------ ACK [MID=1234], 2.05 Content, 2:0/1/128 |
| |
| CON [MID=1235], GE///////////////////////// |
| |
| (timeout) |
| |
| CON [MID=1235], GET, /status, 2:2/0/64 ------> |
| |
| <------ ACK [MID=1235], 2.05 Content, 2:2/1/64 |
: :
: ... :
: :
| CON [MID=1238], GET, /status, 2:5/0/64 ------> |
| |
| <------ ACK [MID=1238], 2.05 Content, 2:5/0/64 |

Abbildung 5: Blockweises GET mit später Verhandlung und verlorenem CON
CLIENT                                                     SERVER
| |
| CON [MID=1234], GET, /status ------> |
| |
| <------ ACK [MID=1234], 2.05 Content, 2:0/1/128 |
| |
| CON [MID=1235], GET, /status, 2:2/0/64 ------> |
| |
| //////////////////////////////////tent, 2:2/1/64 |
| |
| (timeout) |
| |
| CON [MID=1235], GET, /status, 2:2/0/64 ------> |
| |
| <------ ACK [MID=1235], 2.05 Content, 2:2/1/64 |
: :
: ... :
: :
| CON [MID=1238], GET, /status, 2:5/0/64 ------> |
| |
| <------ ACK [MID=1238], 2.05 Content, 2:5/0/64 |

Abbildung 6: Blockweises GET mit später Verhandlung und verlorenem ACK

3.2. Block1-Beispiele

Die folgenden Beispiele demonstrieren einen PUT-Austausch; ein POST-Austausch sieht genauso aus, mit unterschiedlichen Anforderungen an Atomizität/Idempotenz. Beachten Sie, dass ähnlich wie bei GET die Antworten auf die Anfragen, die ein More-Bit in der Block1-Anfrageoption haben, vorläufig sind und den Antwortcode 2.31 (Continue) tragen; nur die endgültige Antwort teilt dem Client mit, dass das PUT erfolgreich war.

CLIENT                                                     SERVER
| |
| CON [MID=1234], PUT, /options, 1:0/1/128 ------> |
| |
| <------ ACK [MID=1234], 2.31 Continue, 1:0/1/128 |
| |
| CON [MID=1235], PUT, /options, 1:1/1/128 ------> |
| |
| <------ ACK [MID=1235], 2.31 Continue, 1:1/1/128 |
| |
| CON [MID=1236], PUT, /options, 1:2/0/128 ------> |
| |
| <------ ACK [MID=1236], 2.04 Changed, 1:2/0/128 |

Abbildung 7: Einfaches atomares blockweises PUT

Ein zustandsloser Server, der die Ressource einfach vor Ort (zustandslos) erstellt/aktualisiert, kann dies anzeigen, indem er das More-Bit in der Antwort nicht setzt (Abbildung 8); in diesem Fall sind die Antwortcodes für jeden aktualisierten Block separat gültig. Dies ist natürlich nur dann ein akzeptables Verhalten des Servers, wenn die potenzielle Inkonsistenz, die während des Laufs der Nachrichtenaustauschsequenz vorhanden ist, nicht zu Problemen führt, z. B. weil die erstellte oder geänderte Ressource noch nicht oder derzeit nicht verwendet wird.

CLIENT                                                     SERVER
| |
| CON [MID=1234], PUT, /options, 1:0/1/128 ------> |
| |
| <------ ACK [MID=1234], 2.04 Changed, 1:0/0/128 |
| |
| CON [MID=1235], PUT, /options, 1:1/1/128 ------> |
| |
| <------ ACK [MID=1235], 2.04 Changed, 1:1/0/128 |
| |
| CON [MID=1236], PUT, /options, 1:2/0/128 ------> |
| |
| <------ ACK [MID=1236], 2.04 Changed, 1:2/0/128 |

Abbildung 8: Einfaches zustandsloses blockweises PUT

Schließlich möchte ein Server, der ein blockweises PUT oder POST empfängt, möglicherweise eine Präferenz für eine kleinere Blockgröße anzeigen (Abbildung 9). In diesem Fall SOLLTE der Client mit einer kleineren Blockgröße fortfahren; wenn er dies tut, MUSS er die Blocknummer anpassen, um in dieser kleineren Größe korrekt zu zählen.

CLIENT                                                     SERVER
| |
| CON [MID=1234], PUT, /options, 1:0/1/128 ------> |
| |
| <------ ACK [MID=1234], 2.31 Continue, 1:0/1/32 |
| |
| CON [MID=1235], PUT, /options, 1:4/1/32 ------> |
| |
| <------ ACK [MID=1235], 2.31 Continue, 1:4/1/32 |
| |
| CON [MID=1236], PUT, /options, 1:5/1/32 ------> |
| |
| <------ ACK [MID=1235], 2.31 Continue, 1:5/1/32 |
| |
| CON [MID=1237], PUT, /options, 1:6/0/32 ------> |
| |
| <------ ACK [MID=1236], 2.04 Changed, 1:6/0/32 |

Abbildung 9: Einfaches atomares blockweises PUT mit Verhandlung

3.3. Kombination von Block1 und Block2

Block-Optionen können in beiden Richtungen eines einzelnen Austauschs verwendet werden. Das folgende Beispiel demonstriert eine blockweise POST-Anfrage, die zu einer separaten blockweisen Antwort führt.

CLIENT                                                     SERVER
| |
| CON [MID=1234], POST, /soap, 1:0/1/128 ------> |
| |
| <------ ACK [MID=1234], 2.31 Continue, 1:0/1/128 |
| |
| CON [MID=1235], POST, /soap, 1:1/1/128 ------> |
| |
| <------ ACK [MID=1235], 2.31 Continue, 1:1/1/128 |
| |
| CON [MID=1236], POST, /soap, 1:2/0/128 ------> |
| |
| <------ ACK [MID=1236], 2.04 Changed, 2:0/1/128, 1:2/0/128 |
| |
| CON [MID=1237], POST, /soap, 2:1/0/128 ------> |
| (no payload for requests with Block2 with NUM != 0) |
| (could also do late negotiation by requesting, |
| e.g., 2:2/0/64) |
| |
| <------ ACK [MID=1237], 2.04 Changed, 2:1/1/128 |
| |
| CON [MID=1238], POST, /soap, 2:2/0/128 ------> |
| |
| <------ ACK [MID=1238], 2.04 Changed, 2:2/1/128 |
| |
| CON [MID=1239], POST, /soap, 2:3/0/128 ------> |
| |
| <------ ACK [MID=1239], 2.04 Changed, 2:3/0/128 |

Abbildung 10: Atomares blockweises POST mit blockweiser Antwort

Dieses Modell sieht eine frühe Verhandlungseingabe für die blockweise Block2-Übertragung vor, wie unten gezeigt.

CLIENT                                                     SERVER
| |
| CON [MID=1234], POST, /soap, 1:0/1/128 ------> |
| |
| <------ ACK [MID=1234], 2.31 Continue, 1:0/1/128 |
| |
| CON [MID=1235], POST, /soap, 1:1/1/128 ------> |
| |
| <------ ACK [MID=1235], 2.31 Continue, 1:1/1/128 |
| |
| CON [MID=1236], POST, /soap, 1:2/0/128, 2:0/0/64 ------> |
| |
| <------ ACK [MID=1236], 2.04 Changed, 1:2/0/128, 2:0/1/64 |
| |
| CON [MID=1237], POST, /soap, 2:1/0/64 ------> |
| (no payload for requests with Block2 with NUM != 0) |
| |
| <------ ACK [MID=1237], 2.04 Changed, 2:1/1/64 |
| |
| CON [MID=1238], POST, /soap, 2:2/0/64 ------> |
| |
| <------ ACK [MID=1238], 2.04 Changed, 2:2/1/64 |
| |
| CON [MID=1239], POST, /soap, 2:3/0/64 ------> |
| |
| <------ ACK [MID=1239], 2.04 Changed, 2:3/0/64 |

Abbildung 11: Atomares blockweises POST mit blockweiser Antwort,
Frühe Verhandlung

3.4. Kombination von Observe und Block2

Im folgenden Beispiel sendet der Server zuerst eine direkte Antwort (Observe-Sequenznummer 62350) auf die anfängliche GET-Anfrage (die resultierende blockweise Übertragung ist wie in Abbildung 4 und wurde daher weggelassen). Die zweite Übertragung wird durch eine 2.05-Benachrichtigung gestartet, die nur den ersten Block enthält (Observe-Sequenznummer 62354); der Client fährt dann fort, um den Rest der Blöcke zu erhalten.

    CLIENT  SERVER
| |
+----->| Header: GET 0x41011636
| GET | Token: 0xfb
| | Uri-Path: status-icon
| | Observe: (empty)
| |
|<-----+ Header: 2.05 0x61451636
| 2.05 | Token: 0xfb
| | Block2: 0/1/128
| | Observe: 62350
| | ETag: 6f00f38e
| | Payload: [128 bytes]
| |
| | (Usual GET transfer left out)
...
| | (Notification of first block)
| |
|<-----+ Header: 2.05 0x4145af9c
| 2.05 | Token: 0xfb
| | Block2: 0/1/128
| | Observe: 62354
| | ETag: 6f00f392
| | Payload: [128 bytes]
| |
+- - ->| Header: 0x6000af9c
| |
| | (Retrieval of remaining blocks)
| |
+----->| Header: GET 0x41011637
| GET | Token: 0xfc
| | Uri-Path: status-icon
| | Block2: 1/0/128
| |
|<-----+ Header: 2.05 0x61451637
| 2.05 | Token: 0xfc
| | Block2: 1/1/128
| | ETag: 6f00f392
| | Payload: [128 bytes]
| |
+----->| Header: GET 0x41011638
| GET | Token: 0xfc
| | Uri-Path: status-icon
| | Block2: 2/0/128
| |
|<-----+ Header: 2.05 0x61451638
| 2.05 | Token: 0xfc
| | Block2: 2/0/128
| | ETag: 6f00f392
| | Payload: [53 bytes]

Abbildung 12: Observe-Sequenz mit blockweiser Antwort

(Beachten Sie, dass die Wahl des Tokens 0xfc in diesem Beispiel willkürlich ist; Token werden in diesem Beispiel nur angezeigt, um zu veranschaulichen, dass die Anfragen für zusätzliche Blöcke das Token der Beobachtungsbeziehung nicht verwenden können. Als allgemeiner Kommentar zu Token gibt es in diesem Dokument keine weitere Erwähnung von Token, da blockweise Übertragungen Token wie jeden anderen CoAP-Austausch behandeln. Wie üblich steht es dem Client frei, Token für jeden Austausch nach Belieben zu wählen.)

Im folgenden Beispiel verwendet der Client ebenfalls eine frühe Verhandlung, um die Blockgröße auf 64 Bytes zu begrenzen.

    CLIENT  SERVER
| |
+----->| Header: GET 0x41011636
| GET | Token: 0xfb
| | Uri-Path: status-icon
| | Observe: (empty)
| | Block2: 0/0/64
| |
|<-----+ Header: 2.05 0x61451636
| 2.05 | Token: 0xfb
| | Block2: 0/1/64
| | Observe: 62350
| | ETag: 6f00f38e
| | Max-Age: 60
| | Payload: [64 bytes]
| |
| | (Usual GET transfer left out)
...
| | (Notification of first block)
| |
|<-----+ Header: 2.05 0x4145af9c
| 2.05 | Token: 0xfb
| | Block2: 0/1/64
| | Observe: 62354
| | ETag: 6f00f392
| | Payload: [64 bytes]
| |
+- - ->| Header: 0x6000af9c
| |
| | (Retrieval of remaining blocks)
| |
+----->| Header: GET 0x41011637
| GET | Token: 0xfc
| | Uri-Path: status-icon
| | Block2: 1/0/64
| |
|<-----+ Header: 2.05 0x61451637
| 2.05 | Token: 0xfc
| | Block2: 1/1/64
| | ETag: 6f00f392
| | Payload: [64 bytes]
....
| |
+----->| Header: GET 0x41011638
| GET | Token: 0xfc
| | Uri-Path: status-icon
| | Block2: 4/0/64
| |
|<-----+ Header: 2.05 0x61451638
| 2.05 | Token: 0xfc
| | Block2: 4/0/64
| | ETag: 6f00f392
| | Payload: [53 bytes]

Abbildung 13: Observe-Sequenz mit früher Verhandlung