受信ハンドラーの実装
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 にリクエストを行う場合、メッセージサイズの上限などはコマンドハンドラーの初期化で 指定 した値に従います。message
とmessage_length
には、プッシュメッセージ全体の JSON 文字列へのポインターとその長さが渡されます。message
のバッファーの終端は\0
でヌルターミネートされていないためご注意ください。
message
として届く JSON の例は、プッシュメッセージの例(Push to App、Push 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
構造体が渡されます。buffer
とbuffer_size
には、プッシュメッセージ全体の JSON 文字列へのポインターとその長さが渡されます。buffer
のバッファーの終端は\0
でヌルターミネートされていないためご注意ください。
buffer
として届く JSON の例は、プッシュメッセージの例(Push to App、Push 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
プッシュハンドラーの関数ポインタを指定します。