This topic describes how to use Message Service (MNS) to send messages from one producer client to multiple consumer clients without exposing the endpoints of consumer clients.

Background information

MNS provides queue-based and topic-based message services. These two types of message services can meet the needs in most business scenarios. The differences between the two types are described as follows:
  • Queue-based message services: One client sends messages to an MNS queue. Multiple clients consume messages by pulling messages from the queue.
  • Topic-based message services: One client sends messages to an MNS topic. Messages are automatically pushed from the MNS server to clients.

MNS allows clients to consume messages in a timely manner by pushing messages from the MNS server to clients. However, the endpoints of consumer clients are exposed. You cannot expose the endpoints of consumer clients in certain scenarios, for example, when you use private networks of an enterprise. To solve the problem, clients can consume messages by pulling messages from the MNS server. You can combine MNS queues and topics to send messages from one client to multiple clients without exposing the endpoints of consumer clients.

Solution

Create a subscription to a topic with a specified queue endpoint so that messages can be pushed from the topic to the queue. Then, consumer clients can pull the messages from the queue. In this case, you can send messages from one client to multiple clients without exposing the endpoints of consumer clients. The following figure shows the procedure.solution

API operations

Java SDK(1.1.5) provides the CloudPullTopic class to solve the problem. MNSClient provides the following API operations to create a CloudPullTopic object:

public CloudPullTopic createPullTopic(TopicMeta topicMeta, Vector<String> queueNameList, boolean needCreateQueue, QueueMeta queueMetaTemplate)

public CloudPullTopic createPullTopic(TopicMeta topicMeta, Vector<String> queueNameList)
The following section describes the parameters:
  • TopicMeta specifies the metadata of a topic.
  • queueNameList specifies a list of queues to which the messages in the topic are pushed.
  • needCreateQueue specifies whether to create the queues that are specified by the queueNameList parameter.
  • queueMetaTemplate specifies the metadata of a queue.

Sample code

CloudAccount account = new CloudAccount(accessKeyId, accessKeySecret, endpoint);
        MNSClient client = account.getMNSClient();

        // build consumer name list.
        Vector<String> consumerNameList = new Vector<String>();
        String consumerName1 = "consumer001";
        String consumerName2 = "consumer002";
        String consumerName3 = "consumer003";
        consumerNameList.add(consumerName1);
        consumerNameList.add(consumerName2);
        consumerNameList.add(consumerName3);
        QueueMeta queueMetaTemplate = new QueueMeta();
        queueMetaTemplate.setPollingWaitSeconds(30);

        try{
            //producer code:
            // create pull topic which will send message to 3 queues for consumer.
            String topicName = "demo-topic-for-pull";
            TopicMeta topicMeta = new TopicMeta();
            topicMeta.setTopicName(topicName);
            CloudPullTopic pullTopic = client.createPullTopic(topicMeta, consumerNameList, true, queueMetaTemplate);

            //publish message and consume message.
            String messageBody = "broadcast message to all the consumers:hello the world.";
            // if we sent raw message,then should use getMessageBodyAsRawString to parse the message body correctly.
            TopicMessage tMessage = new RawTopicMessage(); 
            tMessage.setBaseMessageBody(messageBody);
            pullTopic.publishMessage(tMessage);

            // consumer code:
            //3 consumers receive the message.
            CloudQueue queueForConsumer1 = client.getQueueRef(consumerName1);
            CloudQueue queueForConsumer2 = client.getQueueRef(consumerName2);
            CloudQueue queueForConsumer3 = client.getQueueRef(consumerName3);

            Message consumer1Msg = queueForConsumer1.popMessage(30);
            if(consumer1Msg ! = null) 
            {
                System.out.println("consumer1 receive message:" + consumer1Msg.getMessageBodyAsRawString());
            }else{
                System.out.println("the queue is empty");
            }

            Message consumer2Msg = queueForConsumer2.popMessage(30);
            if(consumer2Msg ! = null) 
            {
                System.out.println("consumer2 receive message:" + consumer2Msg.getMessageBodyAsRawString());
            }else{
                System.out.println("the queue is empty");
            }

            Message consumer3Msg = queueForConsumer3.popMessage(30);
            if(consumer3Msg ! = null) 
            {
                System.out.println("consumer3 receive message:" + consumer3Msg.getMessageBodyAsRawString());
            }else{
                System.out.println("the queue is empty");
            }

            // delete the pullTopic.
            pullTopic.delete();
        }catch(ClientException ce)
        {
            System.out.println("Something wrong with the network connection between client and MNS service."
                    + "Please check your network and DNS availablity.");
            ce.printStackTrace();
        }
        catch(ServiceException se)
        {
            /*you can get more MNS service error code in following link.
             https://www.alibabacloud.com/help/en/doc-detail/27501.htm
            */
            se.printStackTrace();
        }

        client.close();