本文介紹使用PHP SDK接入阿里云物聯網平臺,接收服務端訂閱消息的示例。
前提條件
已獲取消費組ID,并訂閱Topic消息。
管理消費組:您可使用物聯網平臺默認消費組(DEFAULT_GROUP)或創建消費組。
配置AMQP服務端訂閱:您可通過消費組訂閱需要的Topic消息。
下載SDK
本示例提供基于Stomp PHP庫的代碼示例,使用STOMP協議和物聯網平臺云端通信。請訪問Stomp PHP下載客戶端和查看使用說明。
Stomp PHP SDK適用的PHP版本,請參見Stomp PHP SDK中composer.json中require
聲明。
因Stomp PHP 5.0.0以下版本存在SDK斷開后可能無法重連問題,建議您下載Stomp PHP 5.0.0或其以上版本SDK。詳細說明,請參見Issues。
您可在PHP項目文件目錄下,執行以下命令,下載Stomp PHP 5.0.0版本的SDK。
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;
use Stomp\StatefulStomp;
//參數說明,請參見AMQP客戶端接入說明文檔。
// 工程代碼泄露可能會導致 AccessKey 泄露,并威脅賬號下所有資源的安全性。以下代碼示例使用環境變量獲取 AccessKey 的方式進行調用,僅供參考
$accessKey = getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
$accessSecret = getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET');
$consumerGroupId = "${YourConsumerGroupId}";
$clientId = "${YourClientId}";
//iotInstanceId:實例ID。
$iotInstanceId = "${YourIotInstanceId}";
$timeStamp = round(microtime(true) * 1000);
//簽名方法:支持hmacmd5,hmacsha1和hmacsha256。
$signMethod = "hmacsha1";
//userName組裝方法,請參見AMQP客戶端接入說明文檔。
//若使用二進制傳輸,則userName需要添加encode=base64參數,服務端會將消息體base64編碼后再推送。具體添加方法請參見下一章節“二進制消息體說明”。
$userName = $clientId . "|authMode=aksign"
. ",signMethod=" . $signMethod
. ",timestamp=" . $timeStamp
. ",authId=" . $accessKey
. ",iotInstanceId=" . $iotInstanceId
. ",consumerGroupId=" . $consumerGroupId
. "|";
$signContent = "authId=" . $accessKey . "×tamp=" . $timeStamp;
//計算簽名,password組裝方法,請參見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);
//心跳設置,需要云端每30s發送一次心跳包。
$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客戶端接入說明。
請確保參數值輸入正確,否則AMQP客戶端接入會失敗。
參數 | 說明 |
accessKey | 登錄物聯網平臺控制臺,將鼠標移至賬號頭像上,然后單擊AccessKey管理,獲取AccessKey ID和AccessKey Secret。 說明 如果使用RAM用戶,您需授予該RAM用戶管理物聯網平臺的權限(AliyunIOTFullAccess),否則將連接失敗。授權方法請參見RAM用戶訪問。 |
accessSecret | |
consumerGroupId | 當前物聯網平臺對應實例中的消費組ID。 登錄物聯網平臺控制臺,在對應實例的 查看您的消費組ID。 |
iotInstanceId | 實例ID。您可在物聯網平臺控制臺的實例概覽頁面,查看當前實例的ID。
|
clientId | 表示客戶端ID,需您自定義,長度不可超過64個字符。建議使用您的AMQP客戶端所在服務器UUID、MAC地址、IP等唯一標識。 AMQP客戶端接入并啟動成功后,登錄物聯網平臺控制臺,在對應實例的 頁簽,單擊消費組對應的查看,消費組詳情頁面將顯示該參數,方便您識別區分不同的客戶端。 |
client | 創建AMQP客戶端與物聯網平臺的連接:
|
運行結果示例
成功:返回類似如下日志信息,表示AMQP客戶端已接入物聯網平臺并成功接收消息。
失敗:返回類似如下日志信息,表示AMQP客戶端連接物聯網平臺失敗。
您可根據日志提示,檢查代碼或網絡環境,然后修正問題,重新運行代碼。
二進制消息體說明
當您需要傳輸二進制數據時,由于STOMP協議為文本協議,需要使用base64編碼參數,否則消息體可能會被截斷。
本示例中,userName需要按以下方法添加encode=base64參數,使服務端將消息體base64編碼后再推送。
$userName = $clientId . "|authMode=aksign"
. ",signMethod=" . $signMethod
. ",timestamp=" . $timeStamp
. ",authId=" . $accessKey
. ",iotInstanceId=" . $iotInstanceId
. ",consumerGroupId=" . $consumerGroupId
. ",encode=base64" . "|";
相關文檔
服務端訂閱消息相關錯誤碼,請參見消息相關錯誤碼。