メインコンテンツまでスキップ

1. はじめに

1.1. 背景

Constrained Application Protocol (CoAP) [RFC7252] は、HTTP [RFC7230] と同様の RESTful サービス [REST] を提供することを目的としていますが、実装の複雑さと交換されるパケットのサイズを削減し、それ自体が高度に制約されたノードで構成される高度に制約されたネットワーク [RFC7228] でこれらのサービスを有用なものにします。

REST のモデルは、クライアントがサーバーとリソースの表現を交換するというものであり、表現はリソースの現在の状態または意図された状態をキャプチャします。サーバーは、その名前空間内のリソースの表現に関する権限を持ちます。リソースの状態に関心のあるクライアントは、サーバーへの要求を開始します。サーバーは、要求時のリソースの最新の表現を含む応答を返します。

このモデルは、クライアントが一定期間にわたってリソースの最新の表現を持つことに関心がある場合にはうまく機能しません。繰り返しポーリングや HTTP ロングポーリング [RFC6202] などの HTTP の既存のアプローチは、重大な複雑さやオーバーヘッドを発生させるため、制約のある環境にはあまり適していません。

このドキュメントで指定されているプロトコルは、CoAP クライアントが CoAP サーバー上のリソースを「観察」するためのメカニズムで CoAP コアプロトコルを拡張します。クライアントはリソースの表現を取得し、クライアントがリソースに関心を持っている限り、この表現をサーバーによって更新するよう要求します。

このプロトコルは、REST のアーキテクチャ特性を維持します。キャッシュとプロキシのサポートを通じて、高いスケーラビリティと効率を実現します。ただし、既存の HTTP ソリューションが解決する問題のセット全体を解決したり、より一般的な問題を解決するパブリッシュ/サブスクライブネットワーク [RFC5989] を置き換えたりする意図はありません。

1.2. プロトコルの概要

このプロトコルは、よく知られているオブザーバーデザインパターン [GOF] に基づいています。このデザインパターンでは、「オブザーバー」と呼ばれるコンポーネントが、「サブジェクト」と呼ばれる特定の既知のプロバイダーに登録し、サブジェクトの状態が変化したときに通知を受け取るようにします。サブジェクトは、登録されたオブザーバーのリストを管理する責任があります。オブザーバーが複数のサブジェクトに関心がある場合、オブザーバーはそれらすべてに個別に登録する必要があります。

                       オブザーバー          サブジェクト
| |
| 登録 |
+------------------->|
| |
| 通知 |
|<-------------------+
| |
| 通知 |
|<-------------------+
| |
| 通知 |
|<-------------------+
| |

図 1: オブザーバーデザインパターン

オブザーバーデザインパターンは、CoAP では次のように実現されます。

サブジェクト: CoAP のコンテキストでは、サブジェクトは CoAP サーバーの名前空間内のリソースです。リソースの状態は、頻繁でない更新から継続的な状態変換まで、時間の経過とともに変化する可能性があります。

オブザーバー: オブザーバーは、任意の時点でリソースの最新の表現を持つことに関心のある CoAP クライアントです。

登録: クライアントは、サーバーへの拡張 GET 要求を開始することによって、リソースへの関心を登録します。ターゲットリソースの表現を返すことに加えて、この要求により、サーバーはクライアントをリソースのオブザーバーのリストに追加します。

通知: リソースの状態が変化するたびに、サーバーはリソースのオブザーバーのリストにある各クライアントに通知します。各通知は、単一の拡張 GET 要求への返信としてサーバーによって送信される追加の CoAP 応答であり、新しいリソース状態の完全で更新された表現を含みます。

以下の図 2 は、CoAP クライアントがリソースへの関心を登録し、3 つの通知を受信する例を示しています。最初の通知は登録時の現在の状態、次の 2 つはリソース状態の変更時です。登録要求と通知の両方は、このドキュメントで定義されている Observe オプションの存在によってそのように識別されます。通知では、Observe オプションはさらに、並べ替え検出用のシーケンス番号を提供します。すべての通知にはクライアントによって指定されたトークンが含まれているため、クライアントはそれらを要求と簡単に関連付けることができます。

                       クライアント            サーバー
| |
| GET /temperature |
| Token: 0x4a | 登録
| Observe: 0 |
+------------------->|
| |
| 2.05 Content |
| Token: 0x4a | 現在の状態
| Observe: 12 | の通知
| Payload: 22.9 Cel |
|<-------------------+
| |
| 2.05 Content |
| Token: 0x4a | 状態変更時
| Observe: 44 | の通知
| Payload: 22.8 Cel |
|<-------------------+
| |
| 2.05 Content |
| Token: 0x4a | 状態変更時
| Observe: 60 | の通知
| Payload: 23.1 Cel |
|<-------------------+
| |

図 2: CoAP におけるリソースの観察

注: このドキュメントでは、「Cel」は「摂氏」を表します。

サーバーがリソースに対するクライアントの継続的な関心を判断できる限り、クライアントはオブザーバーのリストに残ります。サーバーは、確認可能な CoAP メッセージで通知を送信して、クライアントからの確認を要求する場合があります。クライアントが登録解除したり、通知を拒否したり、通知の送信が数回の送信試行後にタイムアウトしたりした場合、クライアントはリソースに関心がなくなったと見なされ、サーバーによってオブザーバーのリストから削除されます。

1.3. 一貫性モデル

クライアントがリソースのオブザーバーのリストにある間、プロトコルの目標は、クライアントによって観察されるリソースの状態を、サーバーの実際の状態と可能な限り同期させることです。

クライアントとサーバーの同期が時々ずれることは避けられません。第一に、リソース状態の変更と通知の受信の間には常に何らかの遅延があります。第二に、通知を含む CoAP メッセージが失われる可能性があり、これにより、クライアントは新しい通知を受信するまで古い状態を想定することになります。第三に、サーバーは誤ってクライアントがリソースに関心がなくなったと結論付ける可能性があり、これにより、サーバーは通知の送信を停止し、クライアントは最終的に関心を再度登録するまで古い状態を想定することになります。

プロトコルは、次のようにこの問題に対処します。

  • 状態変更後に現在の表現をクライアントに送信するためのベストエフォート型のアプローチに従います。クライアントは、状態変更後にできるだけ早く新しい状態を確認する必要があり、できるだけ多くの状態を確認する必要があります。ただし、これは輻輳制御によって制限されるため、クライアントはリソースが通過する可能性のあるすべての状態を観察できるとは限りません。

  • 観察された状態と実際の状態の同期がずれていても許容される最大期間で通知にラベルを付けます。受信した通知の経過時間がこの制限に達すると、クライアントは新しい通知を受信するまで、同封された表現を使用できません。

  • 結果整合性の原則に基づいて設計されています。リソースが新しい状態変更を受けない場合、最終的にすべての登録されたオブザーバーが最新のリソース状態の現在の表現を持つことをプロトコルは保証します。

1.4. 観察可能なリソース

CoAP サーバーは、リソースがどのような条件下で状態を変更するか、したがってオブザーバーに新しいリソース状態がいつ通知されるかを決定する権限を持ちます。このプロトコルは、トリガーまたはしきい値を設定するための明示的な手段を提供しません。アプリケーションのコンテキストで役立つ方法で状態を変更する観察可能なリソースを公開するかどうかは、サーバー次第です。

たとえば、温度センサーが接続された CoAP サーバーは、次のリソースの 1 つ以上を公開できます。

  • <coap://server/temperature>: 数秒ごとに状態を温度センサーの現在の読み取り値に変更します。

  • <coap://server/temperature/felt>: 温度の読み取り値が特定の設定済みのしきい値を下回るたびに状態を「COLD」に変更し、読み取り値が 2 番目のわずかに高いしきい値を超えるたびに「WARM」に変更します。

  • <coap://server/temperature/critical?above=42>: クライアント指定のパラメータ値に基づいて状態を変更します。温度がしきい値を超えた場合は数秒ごとに現在の温度読み取り値に変更し、読み取り値がしきい値を下回った場合は「OK」に変更します。

  • <coap://server/?query=select+avg(temperature)+from+Sensor.window:time(30sec)>: 任意の複雑さの式を受け入れ、それに応じて状態を変更します。

したがって、特定の条件下で状態を変更する CoAP リソースを設計することにより、生のセンサーデータを継続的に提供するのではなく、これらの条件が発生したときにのみクライアントを更新することが可能です。リソースをパラメータ化することにより、これはサーバーによって定義された条件に限定されず、クライアントによって指定された任意の複雑なクエリに拡張できます。したがって、アプリケーション設計者は、想定されるアプリケーションと関連するデバイスに正確に適した複雑さのレベルを選択でき、プロトコルに組み込まれた「万能の」メカニズムに制約されません。

1.5. 要件の表記

このドキュメントのキーワード "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", および "OPTIONAL" は、RFC 2119 [RFC2119] で説明されているように解釈されます。