Publish and receive messages with topics
This example walks through the complete topic-based messaging lifecycle with the Simple Message Queue (formerly MNS) SDK for PHP: create a topic, subscribe a queue endpoint, publish messages, receive them, and clean up resources.
All steps use the same client instance created in the Set up the client section. For the complete runnable file, see CreateTopicAndPushMessageToQueue.php on GitHub.
Prerequisites
Before you begin, make sure that you have:
SMQ SDK for PHP installed
An endpoint and access credential configured
Set up the client
All operations in this example require an SMQ client instance. Create the client with your endpoint and access credentials:
<?php
require_once __DIR__ . '/vendor/autoload.php';
use AliyunMNS\Client;
use AliyunMNS\Constants;
use AliyunMNS\Exception\MessageNotExistException;
use AliyunMNS\Model\SubscriptionAttributes;
use AliyunMNS\Requests\PublishBase64MessageRequest;
use AliyunMNS\Requests\PublishMessageRequest;
use AliyunMNS\Requests\CreateTopicRequest;
use AliyunMNS\Requests\CreateQueueRequest;
use AliyunMNS\Exception\MnsException;
// Load credentials from environment variables.
// For credential configuration, see: https://www.alibabacloud.com/help/en/mns/developer-reference/php-configure-access-domain-names-and-credentials
$accessId = getenv(Constants::ALIYUN_AK_ENV_KEY);
$accessKey = getenv(Constants::ALIYUN_SK_ENV_KEY);
$endPoint = "<your-endpoint>"; // Example: https://1234567890123456.mns.cn-hangzhou.aliyuncs.com
$client = new Client($endPoint, $accessId, $accessKey);Replace the following placeholder with your actual value:
| Placeholder | Description | Example |
|---|---|---|
<your-endpoint> | Your SMQ endpoint URL | https://1234567890123456.mns.cn-hangzhou.aliyuncs.com |
Step 1: Create a topic
Create a topic that serves as the message channel. Messages published to this topic are delivered to all subscribers.
$topicName = "MyTopicExample";
$request = new CreateTopicRequest($topicName);
try {
$res = $client->createTopic($request);
echo "Topic created.\n";
} catch (MnsException $e) {
echo "Failed to create topic: " . $e . "\n";
return;
}
$topic = $client->getTopicRef($topicName);Step 2: Create a queue for receiving messages
Create a queue that acts as the subscription endpoint. When messages are published to the topic, SMQ pushes them to this queue.
$queueName = "MyQueueExample";
$request = new CreateQueueRequest($queueName);
try {
$res = $client->createQueue($request);
echo "Queue created.\n";
} catch (MnsException $e) {
echo "Failed to create queue: " . $e . "\n";
return;
}
$queue = $client->getQueueRef($queueName);Step 3: Subscribe the queue to the topic
Link the queue to the topic by creating a subscription. The BACKOFF_RETRY strategy retries failed deliveries with exponential backoff. The SIMPLIFIED notify content format sends only the message body without metadata wrappers.
$subscriptionName = "MySubscriptionExample";
$attributes = new SubscriptionAttributes(
$subscriptionName,
$topic->generateQueueEndpoint($queueName), // Generate the queue endpoint URL
'BACKOFF_RETRY', // Retry policy
'SIMPLIFIED' // Notify content format
);
try {
$topic->subscribe($attributes);
echo "Subscription created.\n";
} catch (MnsException $e) {
echo "Failed to subscribe: " . $e . "\n";
return;
}Step 4: Publish messages
Publish a raw message
Use PublishMessageRequest to send a plain-text message without encoding:
$messageBody = "test";
$request = new PublishMessageRequest($messageBody);
try {
$res = $topic->publishMessage($request);
echo "Raw message published.\n";
} catch (MnsException $e) {
echo "Failed to publish raw message: " . $e . "\n";
return;
}Publish a Base64-encoded message
Use PublishBase64MessageRequest to send a Base64-encoded message. The SDK handles encoding automatically.
For more information about encoding options, see Encode a message body.
$messageBody = "test";
$request = new PublishBase64MessageRequest($messageBody);
try {
$res = $topic->publishMessage($request);
echo "Base64-encoded message published.\n";
} catch (MnsException $e) {
echo "Failed to publish Base64-encoded message: " . $e . "\n";
return;
}Step 5: Receive messages from the queue
Poll the queue to retrieve messages pushed from the topic. After processing each message, delete it from the queue to prevent redelivery.
If the published messages were Base64-encoded, decode them on the receiving side.
while (true) {
try {
$res = $queue->receiveMessage(3); // Wait up to 3 seconds for a message
echo "Message received: " . $res->getMessageBody() . "\n";
// Delete the message after processing
$receiptHandle = $res->getReceiptHandle();
$queue->deleteMessage($receiptHandle);
echo "Message deleted.\n";
break;
} catch (MessageNotExistException $e) {
// No message available yet. Retry.
echo "No new messages. Retrying...\n";
} catch (MnsException $e) {
echo "Failed to receive message: " . $e . "\n";
break;
}
}Step 6: Clean up resources
After you finish, remove the subscription, topic, and queue to avoid unnecessary charges.
// Unsubscribe
try {
$topic->unsubscribe($subscriptionName);
echo "Unsubscribed.\n";
} catch (MnsException $e) {
echo "Failed to unsubscribe: " . $e . "\n";
return;
}
// Delete the topic
try {
$client->deleteTopic($topicName);
echo "Topic deleted.\n";
} catch (MnsException $e) {
echo "Failed to delete topic: " . $e . "\n";
return;
}
// Delete the queue
try {
$client->deleteQueue($queueName);
echo "Queue deleted.\n";
} catch (MnsException $e) {
echo "Failed to delete queue: " . $e . "\n";
return;
}What's next
Encode a message body -- Choose between raw and Base64 encoding
Configure endpoints and access credentials -- Credential and endpoint configuration options
CreateTopicAndPushMessageToQueue.php -- Complete runnable example on GitHub