队列使用示例

本文介绍使用PHP SDK发送SMQ消息时的准备工作及示例代码。

准备工作

  • 已安装SDK

  • 已配置访问域名及凭证

  • CreateQueueAndSendMessage.php的代码最上方有一些设置,使用SDK时需按照注释进行设置。

    // require替换为composer下载的vendor下的autoload文件。
    require_once __DIR__ . '/vendor/autoload.php';
    
    // 代码里需要用的一些 PHP class。  
    use AliyunMNS\Client;
    use AliyunMNS\Requests\SendMessageRequest;
    use AliyunMNS\Requests\CreateQueueRequest;
    use AliyunMNS\Exception\MnsException;

消息体编码选择

当消息体无特殊字符时,建议您不使用Base64编码。

  • 发送消息时使用message.setMessageBodyAsRawString方法设置消息体。

  • 接收消息时使用meesage.getMessageBodyAsRawString方法获取消息体。

发送消息

完整示例代码下载,请参见CreateQueueAndSendMessage

// 1.首先获取Queue的实例。
// PHP SDK默认会对发送的消息做Base64 Encode,对接收到的消息做Base64 Decode。
// 如果不希望SDK做这样的Base64操作,可以在getQueueRef的时候,传入参数$base64=FALSE。即$queue = $this->client->getQueueRef($queueName, FALSE);
$queue = $this->client->getQueueRef($queueName);

$messageBody = "test";
// 2.生成一个SendMessageRequestItem对象。
// SendMessageRequestItem对象本身也包含了DelaySeconds和Priority属性可以设置。
// 对于Message的属性,请参见QueueMessage。
$bodyMD5 = md5(base64_encode($messageBody));
$request = new SendMessageRequestItem($messageBody);
try
{
        $res = $queue->sendMessage($request)
        // 3.消息发送成功。
        echo "MessageSent! \n";
}
catch (MnsException $e)
{
        // 4.可能因为网络错误,或MessageBody过大等原因造成发送消息失败,这里CatchException并做对应的处理。
        echo "SendMessage Failed: " . $e;
        return;
}

接收和删除消息

完整示例代码下载,请参见CreateQueueAndSendMessage

$receiptHandle = NULL;
try
{
        // 1.直接调用receiveMessage函数。
        // receiveMessage函数接受waitSeconds参数,无特殊情况建议设置为30。
        // waitSeconds非0表示这次receiveMessage是一次http long polling,如果queue内没有message,那么这次request会在server端等到queue内有消息才返回。最长等待时间为waitSeconds的值,最大为30。
        $res = $queue->receiveMessage(30);
        echo "ReceiveMessage Succeed! \n";
        if (strtoupper($bodyMD5) == $res->getMessageBodyMD5())
        {
             echo "You got the message sent by yourself! \n";
        }
        // 2.获取ReceiptHandle,这是一个有时效性的Handle,可以用来设置Message的各种属性和删除Message。更多信息,请参见QueueMessage。
        $receiptHandle = $res->getReceiptHandle();
}
catch (MnsException $e)
{
        // 3.和CreateQueue和SendMessage一样,ReceiveMessage也有可能出错,所以加上CatchException并做对应的处理。
        echo "ReceiveMessage Failed: " . $e;
        return;
}

// 这里是您处理消息的逻辑。Sample里就直接略过这一步。
// 如果这里发生了程序崩溃或卡住等异常情况,对应的Message会在VisibilityTimeout之后重新可见,从而可以被其他进程处理,避免消息丢失。

// 4.消息已经处理完成,从队列里删除这条消息。
try
{
        // 5.直接调用deleteMessage。
        $res = $queue->deleteMessage($receiptHandle);
        echo "DeleteMessage Succeed! \n";
}
catch (MnsException $e)
{
        // 6.这里CatchException并做异常处理。
        // 如果是receiptHandle已经过期,那么ErrorCode是MessageNotExist,表示通过这个receiptHandle已经找不到对应的消息。
        // 为了保证receiptHandle不过期,VisibilityTimeout的设置需要保证足够消息处理完成。并且在消息处理过程中,也可以调用changeMessageVisibility这个函数来延长消息的VisibilityTimeout时间。
        echo "DeleteMessage Failed: " . $e;
        return;
}