PHP SDK を使用して IoT Platform に接続し、サーバーサイドサブスクリプションメッセージを受信します。
前提条件
トピックのメッセージをサブスクライブするコンシューマーグループの ID を取得します。
DEFAULT_GROUP という名前のデフォルトのコンシューマーグループを使用するか、IoT Platform コンソールでコンシューマーグループを作成できます。詳細については、「コンシューマーグループを管理する」をご参照ください。
コンシューマーグループを使用して、トピックのメッセージをサブスクライブできます。詳細については、「AMQP サーバー側サブスクリプションを設定する」をご参照ください。
SDK のダウンロード
このサンプルコードでは、Stomp PHP ライブラリを使用して、STOMP プロトコル経由で IoT Platform と通信します。Stomp PHP にアクセスして、クライアントをダウンロードし、手順を確認してください。
対応 PHP バージョンについては、「Stomp PHP SDK の composer.json ファイル内の require 宣言」をご参照ください。
Stomp PHP バージョン 5.0.0 より前のバージョンには、既知の再接続に関する問題があります。バージョン 5.0.0 以降を推奨します。詳細については、「Issues」をご参照ください。
PHP プロジェクトディレクトリで次のコマンドを実行して、Stomp PHP 5.0.0 をインストールします。
composer require stomp-php/stomp-php 5.0.0
サンプルコード
<?php
require __DIR__ . '/vendor/autoload.php';
use Stomp\Client;
use Stomp\Network\Observer\Exception\HeartbeatException;
use Stomp\Network\Observer\ServerAliveObserver;
// パラメーターの詳細については、AMQP クライアント接続に関するドキュメントを参照してください。
// 警告:AccessKey のハードコーディングはセキュリティリスクです。この例では、セキュリティを強化するために環境変数から取得しています。
$accessKey = getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
$accessSecret = getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET');
$consumerGroupId = "${YourConsumerGroupId}";
$clientId = "${YourClientId}";
// iotInstanceId:IoT Platform インスタンスの ID。
$iotInstanceId = "${YourIotInstanceId}";
$timeStamp = round(microtime(true) * 1000);
// 署名アルゴリズム。サポートされる値は hmacmd5、hmacsha1、hmacsha256 です。
$signMethod = "hmacsha1";
// ユーザー名の構成方法については、AMQP クライアント接続に関するドキュメントを参照してください。
// バイナリデータを送信するには、ユーザー名に encode=base64 パラメーターを追加します。サーバーは、メッセージを送信する前にメッセージ本文を Base64 でエンコードします。詳細については、「バイナリメッセージ本文」セクションを参照してください。
$userName = $clientId . "|authMode=aksign"
. ",signMethod=" . $signMethod
. ",timestamp=" . $timeStamp
. ",authId=" . $accessKey
. ",iotInstanceId=" . $iotInstanceId
. ",consumerGroupId=" . $consumerGroupId
. "|";
$signContent = "authId=" . $accessKey . "×tamp=" . $timeStamp;
// 署名を計算します。パスワードの構成方法については、AMQP クライアント接続に関するドキュメントを参照してください。
$password = base64_encode(hash_hmac("sha1", $signContent, $accessSecret, $raw_output = TRUE));
// 接続エンドポイント。詳細については、AMQP クライアント接続に関するドキュメントを参照してください。
$client = new Client('ssl://${YourHost}:61614');
$sslContext = ['ssl' => ['verify_peer' => true, 'verify_peer_name' => false], ];
$client->getConnection()->setContext($sslContext);
// サーバーハートビートをリッスンします。
$observer = new ServerAliveObserver();
$client->getConnection()->getObservers()->addObserver($observer);
// ハートビート設定。クライアントは、30 秒ごとにサーバーからハートビートパケットを受信します。
$client->setHeartbeat(0, 30000);
$client->setLogin($userName, $password);
try {
$client->connect();
}
catch(StompException $e) {
echo "failed to connect to server, msg:" . $e->getMessage() , PHP_EOL;
}
// 接続に成功すると、処理が続行されます。
$stomp = new StatefulStomp($client);
$stomp->subscribe('/topic/#');
echo "connect success";
while (true) {
try {
// 接続ステータスを確認します。
if (!$client->isConnected()) {
echo "connection not exists, will reconnect after 10s.", PHP_EOL;
sleep(10);
$client->connect();
$stomp->subscribe('/topic/#');
echo "connect success", PHP_EOL;
}
// ここにメッセージ処理ロジックを追加します。
echo $stomp->read();
}
catch(HeartbeatException $e) {
echo 'The server failed to send us heartbeats within the defined interval.', PHP_EOL;
$stomp->getClient()->disconnect();
} catch(Exception $e) {
echo 'process message occurs error: '. $e->getMessage() , PHP_EOL;
$stomp->getClient()->disconnect();
}
}
次の表のパラメーターの説明に基づいて、上記のコードのパラメーターを設定できます。その他のパラメーターの詳細については、「AMQP クライアントを IoT Platform に接続する」をご参照ください。
有効なパラメーター値を指定してください。そうでない場合、AMQP クライアントは IoT Platform への接続に失敗します。
|
パラメーター |
説明 |
|
accessKey |
IoT Platform コンソールにログオンし、右上隅にあるプロフィール画像にポインターを合わせ、[アクセスキー管理] をクリックしてアクセスキー ID とアクセスキーシークレットを取得します。 説明
RAM ユーザーを使用する場合は、IoT Platform を管理する権限 (AliyunIOTFullAccess) を RAM ユーザーに付与する必要があります。付与しない場合、接続が失敗します。権限を付与する方法の詳細については、「RAM User Access」をご参照ください。 |
|
accessSecret |
|
|
consumerGroupId |
IoT Platform インスタンスのコンシューマーグループの ID。 コンシューマーグループの ID を表示するには、次の手順を実行します。IoT Platform コンソールにログインし、管理するインスタンスのカードをクリックします。左側のナビゲーションウィンドウで、 を選択します。コンシューマーグループの ID は、[コンシューマーグループ] タブに表示されます。 |
|
iotInstanceId |
インスタンスの ID。 [IoT Platform コンソール] の [概要] ページで確認できます。
|
|
clientId |
クライアントの ID。カスタム ID を指定する必要があります。 ID は 1 ~ 64 文字の長さである必要があります。クライアントが実行されているサーバーの UUID、MAC アドレス、IP アドレスなど、一意の識別子をクライアント ID として使用することをお勧めします。 AMQP クライアントが IoT Platform に接続して起動した後、次の手順を実行してクライアントの詳細を表示します。IoT Platform コンソールにログインし、管理する インスタンス のカードをクリックします。左側のナビゲーションウィンドウで、 を選択します。[コンシューマーグループ] タブで、管理するコンシューマーグループを見つけ、[操作] 列の [表示] をクリックします。各クライアントの ID は、[コンシューマーグループステータス] タブに表示されます。クライアント ID を使用して、クライアントを簡単に識別できます。 |
|
client |
AMQP クライアントと IoT Platform 間の接続を作成します:
|
サンプル結果
-
成功:次のようなログメッセージが返されると、AMQP クライアントが IoT Platform に接続し、メッセージを正常に受信したことを示します。
$ php newfile.php connect successMESSAGE qos:1 destination:/xxx/thing/event/property/post message-id:xxx2096 topic:/xxx/xxx2/thing/event/property/post subscription:xxx generateTime:xxx {"deviceType":"CustomCategory","iotId":"xxx","requestId":"1614065952794","checkFailedData":{},"productKey":"xxx","gmtCreate":1614065819600,"deviceName":"xxx","items":{"Temperature":{"value":11,"time":1614065819597},"Humidity":{"value":28,"time":1614065819597}}} MESSAGE qos:1 destination:/xxx/xxx2/thing/event/property/post -
失敗:次のようなログメッセージが返されると、AMQP クライアントが IoT Platform への接続に失敗したことを示します。
ログに基づいてコードまたはネットワーク環境を確認し、問題を解決してから、コードを再度実行できます。
xxx>php newfile.php PHP Fatal error: Uncaught Stomp\Exception\ConnectionException: Failed to connect. (0: php_network_getaddresses: getaddrinfo failed: □) Fatal error: Uncaught Stomp\Exception\ConnectionException: Failed to connect. (0: php_network_getaddresses: getaddrinfo failed: □) (Host: xxx.un cs.com) in xxx\stomp-php\stomp-php\src\Network\Connection.php:417 Stack trace: #0 xxx\stomp-php\stomp-php\src\Network\Connection.php(353): Stomp\Network\Connection->connectSocket(Array) #1 xxx\stomp-php\stomp-php\src\Network\Connection.php(327): Stomp\Network\Connection->getConnection() #2 xxx\stomp-php\stomp-php\src\Client.php(207): Stomp\Network\Connection->connect() #3 xxx.php(45): Stomp\Client->connect() #4 xxx.php(56): start_consume() #5 {main} Next Stomp\Exception\ConnectionException: Could not connect to a broker (Host: xxx) in xxx\stomp -php\src\Network\Connection.php:358 Stack t in xxx\vendor\stomp-php\stomp-php\src\Network\Connection.php on line 358
バイナリメッセージ本文
バイナリデータを送信するには、Base64 エンコーディングパラメーターを使用してください。STOMP はテキストベースのプロトコルであるため、エンコーディングを行わないと、メッセージ本文が切り捨てられる可能性があります。
次に示すように、userName に encode=base64 パラメーターを追加します。サーバーは、メッセージを送信する前にメッセージ本文を Base64 でエンコードします。
$userName = $clientId . "|authMode=aksign"
. ",signMethod=" . $signMethod
. ",timestamp=" . $timeStamp
. ",authId=" . $accessKey
. ",iotInstanceId=" . $iotInstanceId
. ",consumerGroupId=" . $consumerGroupId
. ",encode=base64" . "|";
関連情報
サーバー側サブスクリプション機能に関連するエラーコードの詳細については、「IoT Platform ログ」トピックのメッセージに関連するエラーコードセクションをご参照ください。