本文介绍使用PHP SDK接入阿里云物联网平台,接收服务端订阅消息的示例。

下载SDK

本示例提供基于Stomp PHP库的Demo,使用STOMP协议和云端通信。请访问Stomp PHP下载客户端和查看使用说明。

代码示例

以下Demo中涉及的参数说明,请参见AMQP客户端接入说明

<?php
require __DIR__ . '/vendor/autoload.php';
use Stomp\Client;
use Stomp\Network\Observer\Exception\HeartbeatException;
use Stomp\Network\Observer\ServerAliveObserver;
use Stomp\StatefulStomp;
function start_consume() {
    //参数说明,请参见AMQP客户端接入说明文档。
    $accessKey = "${YourAccessKeyId}";
    $accessSecret = "${YourAccessKeySecret}";
    $consumerGroupId = "${YourConsumerGroupId}";
    //iotInstanceId:购买的实例请填写实例ID,公共实例请填空字符串""。
    $iotInstanceId = "${YourIotInstanceId}";
    $timeStamp = round(microtime(true) * 1000);
    //签名方法:支持hmacmd5,hmacsha1和hmacsha256。
    $signMethod = "hmacsha1";
    $clientId = "${YourClientId}";
    //userName组装方法,请参见AMQP客户端接入说明文档。
    //若使用二进制传输,则userName需要添加encode=base64参数,服务端会将消息体base64编码后再推送。具体添加方法请参见下一章节“二进制消息体说明”。
    $userName = $clientId . "|authMode=aksign"
                . ",signMethod=" . $signMethod
                . ",timestamp=" . $timeStamp
                . ",authId=" . $accessKey
                . ",iotInstanceId=" . $iotInstanceId
                . ",consumerGroupId=" . $consumerGroupId
                . "|";
    $signContent = "authId=" . $accessKey . "&timestamp=" . $timeStamp;
    //计算签名,password组装方法,请参见AMQP客户端接入说明文档。
    $password = base64_encode(hash_hmac("sha1", $signContent, $accessSecret, $raw_output = TRUE));
    //接入域名,请参见AMQP客户端接入说明文档。端口为61614。
    $client = new Client('ssl://${host}:61614');
    $sslContext = ['ssl' => ['verify_peer' => true, 'verify_peer_name' => false], ];
    $client->getConnection()->setContext($sslContext);

    //服务端心跳监听。
    $observer = new ServerAliveObserver();
    $client->getConnection()->getObservers()->addObserver($observer);
    //心跳设置,需要云端每10s发送一次心跳包。
    $client->setHeartbeat(0, 10000);
    $client->setLogin($userName, $password);
    try {
        $client->connect();
    }
    catch(StompException $e) {
        echo "failed to connect to server, msg:" . $e->getMessage() , PHP_EOL;
    }
    //code works as usual
    $stomp = new StatefulStomp($client);
    $stomp->subscribe('/topic/#');
    return $stomp;
}

$stomp = start_consume();

while (true) {
    if ($stomp == null || !$stomp->getClient()->isConnected()) {
        echo "connection not exists, will reconnect after 10s.", PHP_EOL;
        sleep(10);
        $stomp = start_consume();
    }

    try {
        //处理消息业务逻辑。
        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协议为文本协议,需要使用base64编码参数,否则消息体可能会被截断。

本示例中,userName需要按以下方法添加encode=base64参数,使服务端将消息体base64编码后再推送。

$userName = $clientId . "|authMode=aksign"
                . ",signMethod=" . $signMethod
                . ",timestamp=" . $timeStamp
                . ",authId=" . $accessKey
                . ",iotInstanceId=" . $iotInstanceId
                . ",consumerGroupId=" . $consumerGroupId
                . ",encode=base64" . "|";