リアルタイム通知

本書では、Things CloudにおけるクラウドからIoTデバイスにへのリアルタイム通知の仕組みについて説明します。

概要

IoTシステムにおいて、クラウドからIoTデバイスに対して何らかの通知を行いたいケースは往々にして存在します。その多くはIoTデバイスに対する制御命令の伝達でしょう。

Things Cloudではこの要請に対し、ロングポーリング(Long Polling)と呼ばれる仕組みを提供します。実装としてはBayeuxプロトコルを採用しており、NAT環境のような制限のあるネットワークにおいても応答性の良いリアルタイム通信を利用することができます。

利用方法

Things Cloudのロングポーリングの機能はリアルタイム通知APIとして提供されます。

本節では、ロングポーリングの利用シーンとして最も適切なオペレーションの発行通知取得のためのリアルタイム通知APIの利用方法について述べます。本節で示す手順はオペレーションが新規に発行されたことに対する通知のみを受け取ることができます。したがってユーザーによるオペレーションのキャンセルなどの通知を受け取ることはできないことに注意してください。

リアルタイム通知APIはオペレーションが新規発行されたことの通知だけでなく、インベントリやメジャーメント、イベント、アラームの発行・更新の通知に対しても利用することができます。詳細はリアルタイム通知APIのリファレンスをご覧ください。こちらの方法を利用することで、オペレーションのキャンセルなどの通知もリアルタイムに取得することが可能となります。

**注意:**リアルタイム通知APIは巨大なデータ量をストリームとして取得(> 100kB/sec)したり、頻繁に更新されるデータを取得(> 50データ/sec)する事を想定してデザインされていません。そのため、リアルタイム通知APIはこのようなユースケースをサポートしません。

リアルタイム通知APIを利用するためには、ハンドシェイクチャネル接続接続 という3つのステップを実行する必要があります。

Long Polling Sequence

ハンドシェイク

ハンドシェイクはリアルタイム通知のやりとりにおける通信方法を決定するために行われます。IoTデバイスはThings Cloudに対応可能な通信プロトコルを伝え、Things Cloudはその応答としてリアルタイム通知を行う上でのクライアントIDを割り当てます。

POST /devicecontrol/notifications
POST /devicecontrol/notifications HTTP/1.1
Content-Type: application/json
...
HTTP/1.1 200 OK
...
[
    {
        "ext": {
            "ack": true
        },
        "minimumVersion": "1.0",
        "clientId": "2m12ypthdvcsj309x0dsnjyvkse",
        "supportedConnectionTypes": [
            "websocket",
            "smartrest-long-polling",
            "long-polling"
        ],
        "channel": "/meta/handshake",
        "version": "1.0",
        "successful": true
    }
]

チャネル接続

チャネル接続はリアルタイム通知を利用してどのIoTデバイスに対する通知を受け取るかを指定するために行われます。IoTデバイスがオペレーション更新通知を受け取る場合は、自デバイスまたは自身の子デバイスに対するオペレーションの更新を受け取ることになるため、"com_cumulocity_model_Agent" : {} のフラグメントを持つIoTデバイスのオペレーションを購読(subscribe)することになります。

POST /devicecontrol/notifications
POST /devicecontrol/notifications HTTP/1.1
Content-Type: application/json
...
HTTP/1.1 200 OK
...
[
    {
        "channel": "/meta/subscribe",
        "subscription": "/143829",
        "successful": true
    }
]

接続

ハンドシェイク及びチャネル接続が完了したら、最後に更新通知を受け取るための接続を行います。この要求は、オペレーションが発行されるか、規定の待機時間が経過するまでThings Cloud側で保留されます。これがロングポーリングの仕組みです。

POST /devicecontrol/notifications
POST /devicecontrol/notifications HTTP/1.1
Content-Type: application/json
...
HTTP/1.1 200 OK
...
[
  {
    "data": {
      "creationTime": "2019-11-11T11:11:28.343+09:00",
      "deviceId": "143829",
      "deviceName": "SampleDevice",
      "self": "<<This Operation URL>>",
      "id": "144100",
      "status": "PENDING",
      "c8y_Configuration": {
        "config": "{\n    \"lang\": \"ja\",\n    \"pollingTime\": 30000\n}"
      },
      "description": "Configuration update"
    },
    "channel": "/143829",
    "id": "10659108"
  },
  {
    "advice": {
      "interval": 0,
      "timeout": 5400000,
      "reconnect": "retry"
    },
    "channel": "/meta/connect",
    "successful": true
  }
]

Things CloudからIoTデバイスに対して接続に対するHTTPレスポンスが返却された場合、直ちに接続を再要求してください。この際、clientIdは前回と同じ値を利用することが可能です。つまりハンドシェイクやチャネル接続を再実施する必要はありません。ただし、接続操作を行う際に何らかのエラー応答が返された場合には、Things Cloudとの接続状態をクリアするために再度ハンドシェイクから実施するべきです。