受信ハンドラーの実装

Thing SDK Embedded では、プッシュ通知を MQTT によって利用できるよう、SDK の内部で MQTT クライアントの機能を実装しています。プッシュメッセージを受信すると、SDK からハンドラーとして登録した関数が呼び出され、独自の処理を実行することができます。

実装方法は、Thing-IF SDK を併用しているかどうかによって異なります。

Thing-IF SDK を併用する場合

Thing-IF SDK を併用する場合、カスタムプッシュハンドラーを使ってプッシュメッセージをフックできます。

Thing-IF SDK は、MQTT の受信処理を実装しています。この処理では、Kii Cloud SDK のプッシュメッセージと、Thing Interaction Framework のコマンドの両方をプッシュ通知として受け取ります。Thing-IF SDK は、まずカスタムプッシュハンドラーにすべてのプッシュメッセージを中継します。カスタムプッシュハンドラーでは、自分が認識できるプッシュメッセージだけを処理し、残りを Thing-IF SDK に戻します。Thing-IF SDK はコマンドとして解釈できるかどうかチェックし、アクションハンドラー を呼び出します。

カスタムプッシュハンドラーでは、戻り値によってプッシュメッセージを処理したかどうかを返します。

  • KII_TRUE を返した場合:プッシュメッセージはアプリケーション独自の処理を行ったため、Thing-IF SDK でのそれ以上の解析は不要であることを意味します。
  • KII_FALSE を返した場合:プッシュメッセージは処理されていないため、コマンドなどの Thing Interaction Framework のメッセージとして解釈する必要があることを意味します。

カスタムプッシュハンドラーの例を以下に示します。ここでは、if の条件で message の内容を判別し、認識できるプッシュメッセージであった場合にのみ処理を行って KII_TRUE を返します。

kii_bool_t custom_push_handler(
        kii_t *kii,
        const char* message,
        size_t message_length)
{
  /* If the message is recognized by the custom push handler */
  if (...) {
    /* Do something. */
    return KII_TRUE;
  }

  /* Let the Thing-IF SDK process the message. */
  return KII_FALSE;
}
  • kii には、コマンドハンドラーの kii_t 構造体が渡されます。カスタムプッシュハンドラーから Kii Cloud にリクエストを行う場合、メッセージサイズの上限などはコマンドハンドラーの初期化で 指定 した値に従います。
  • messagemessage_length には、プッシュメッセージ全体の JSON 文字列へのポインターとその長さが渡されます。message のバッファーの終端は \0 でヌルターミネートされていないためご注意ください。

message として届く JSON の例は、プッシュメッセージの例(Push to AppPush to User)をご覧ください。JSON の解析には kii_json ライブラリーを利用できます。

カスタムプッシュハンドラーは、Thing-IF SDK の 初期化コードの実装 の際に、 kii_thing_if_command_handler_resource_t 構造体の custom_push_handler として指定します。指定がない場合、カスタムプッシュハンドラーは使用せず、すべてのプッシュメッセージを Thing Interaction Framework のコマンドとして解釈します。

kii_thing_if_command_handler_resource_t command_handler_resource;
......
command_handler_resource.custom_push_handler = custom_push_handler;
......
result = init_kii_thing_if(&kii_thing_if, EX_APP_ID, EX_APP_KEY, EX_APP_SITE,
        &command_handler_resource, &state_updater_resource, NULL);

Thing-IF SDK を併用しない場合

Thing-IF SDK を併用しない場合、プッシュハンドラーを新しく設定します。同時に MQTT を使ってプッシュ通知を処理するためのスレッドを生成します。

プッシュハンドラーの例を以下に示します。

void received_callback(kii_t* kii, char* buffer, size_t buffer_size)
{
    char copy[1024];
    memset(copy, 0x00, sizeof(copy));
    strncpy(copy, buffer, sizeof(copy) - 1);
    printf("buffer_size: %lu\n", buffer_size);
    printf("recieve message: %s\n", copy);
}
  • kii には、この後示す kii_push_start_routine に渡した kii_t 構造体が渡されます。
  • bufferbuffer_size には、プッシュメッセージ全体の JSON 文字列へのポインターとその長さが渡されます。buffer のバッファーの終端は \0 でヌルターミネートされていないためご注意ください。

buffer として届く JSON の例は、プッシュメッセージの例(Push to AppPush to User)をご覧ください。JSON の解析には kii_json ライブラリーを利用できます。

プッシュハンドラーは次の API で指定します。実行すると、MQTT の受信スレッドと、MQTT の PINGREQ コマンドを定期的に送信するスレッドの、2 つを生成します。指定したプッシュハンドラーは、生成された MQTT の受信スレッドから呼び出されます。

/* Set MQTT processing parameters. */
#define TASK_PRIORITY 0
#define PING_REQ_TASK_PRIO 0

/* Start the push notification receiving routine. */
ret = kii_push_start_routine(&kii_for_push, TASK_PRIORITY, PING_REQ_TASK_PRIO, received_callback);
if (ret != 0) {
  /* Handle the error. */
  return;
}

ここでは、以下の値を設定しています。

  • &kii_for_push

    プッシュ通知で使用する kii_t 構造体を指定します。

    ここで指定する kii_t 構造体は MQTT 受信スレッドで使用されるため、 kii_push_start_routine の呼び出し元スレッドでは、これ以降、第 1 引数で渡した kii_t 構造体を利用することはできません。kii_t 構造体は送受信のバッファーなどを含んでいるため、別スレッドで同時に使用すると、再現性がないバグの原因になります。詳しくは、SDK の初期化 を参照してください。

  • TASK_PRIORITY

    MQTT の受信監視を行うスレッドの優先度を指定します。この値は、スレッド作成用の task_create_cb の第 6 引数 priority にそのまま中継されます。このパラメーターは、スレッドやタスクの優先度の指定で使用することを想定していますが、最終的な用途は OS 依存の処理次第です。Linux の実装例は、Thing SDK Embedded のリファレンス実装のソースファイル kii/Linux/kii_task_impl.c をご覧ください。

  • PING_REQ_TASK_PRIO

    MQTT 受信処理で PINGREQ を定期的に送信するためのスレッドの優先度を指定します。指定方法は TASK_PRIORITY と同じです。

  • received_callback

    プッシュハンドラーの関数ポインタを指定します。