Azure Messaging-ServiceBus Messaging消息队列技术系列6-消息回执

上篇博文中我们介绍了Azure Messaging的重复消息机制、At most once 和At least once.

 Azure Messaging-ServiceBus Messaging消息队列技术系列5-重复消息:at-least-once at-most-once

本文中我们主要研究并介绍Azure Messaging的消息回执机制:实际应用场景:

同步收发场景下,消息生产者和消费者双向应答模式,例如:张三写封信送到邮局中转站,然后李四从中转站获得信,然后在写一份回执信,放到中转站,然后张三去取,当然张三写信的时候就得写明回信地址。还

有,生成订单编号场景,发送一个生成订单编号的消息,消息消费者接收生成订单编号的消息,并通过消息回执返回。

Azure Messaging的消息回执机制主要通过:基于带会话的Queue/Topic、SessionId、ReplyTo属性来实现

在代码实现中,我们需要:

1. 两个工作线程,一个线程用于消息发送和接收回执消息,一个线程用于消息接收和发送消息回执。

2. 一个会话标识:ReceiptSession  

3. 两个队列Queue:RequestQueue:发送消息、接收消息,ResponseQueue:发送回执消息,接收回执消息。

直接Show Code:

首先,我们在ServiceBusMQManager增加一个线程安全的创建带回话的QueueClient方法:

复制代码
private static object syncObj = new object();
        /// <summary>
        /// 获取要求会话带Session的QueueClient
        /// </summary>
        /// <param name="queueName">队列名称</param>
        /// <returns>QueueClient</returns>
        public QueueClient GetSessionQueueClient(string queueName)
        {
            var namespaceClient = NamespaceManager.Create();
            if (!namespaceClient.QueueExists(queueName))
            {
                lock (syncObj)
                {
                    if (!namespaceClient.QueueExists(queueName))
                    {
                        var queue = new QueueDescription(queueName) { RequiresSession = true };
                        namespaceClient.CreateQueue(queue);
                    }
                }
            }

            return QueueClient.Create(queueName, ReceiveMode.ReceiveAndDelete);
        }
复制代码

然后我们定义一些常量:

复制代码
        private static readonly string ReplyToSessionId = "ReceiptSession";

        const double ResponseMessageTimeout = 20.0;

        private static readonly string requestQueueName = "RequestQueue";

        private static readonly string responseQueueName = "ResponseQueue";
复制代码

实现发送并接收回执消息的方法:

复制代码
        /// <summary>
        /// 发送并接收回执消息
        /// </summary>
        /// <param name="bills"></param>
        public static void SendMessage()
        {
            var manager = new ServiceBusUtils();
            var responseClient = manager.GetSessionQueueClient(responseQueueName);
            var requestClient = manager.GetSessionQueueClient(requestQueueName);

            var messsageReceiver = responseClient.AcceptMessageSession(ReplyToSessionId);
            var order = CreateSalesOrder(1);

            //发送消息
            var message = new BrokeredMessage(order);
            message.Properties.Add("Type", order.GetType().ToString());
            message.SessionId = ReplyToSessionId;
            message.MessageId = "OrderMessage001";
            message.ReplyTo = responseQueueName;
            requestClient.Send(message);
            Console.WriteLine("Send message: " + message.MessageId + ", SalesOrder ID: " + order.OrderID);

            //接收消息回执
            var receivedMessage = messsageReceiver.Receive(TimeSpan.FromSeconds(ResponseMessageTimeout * 2));

            var receivedOrder = receivedMessage.GetBody<SalesOrder>();
            Console.WriteLine("Receive receipt message: " + receivedMessage.MessageId + ", SalesOrder ID: " + receivedOrder.OrderID);
            messsageReceiver.Close();
        }
复制代码

实现接收消息并发送回执方法:

复制代码
 1         /// <summary>
 2         /// 接收消息并回执
 3         /// </summary>
 4         public static void ReceiveMessage()
 5         {
 6             var manager = new ServiceBusUtils();
 7 
 8             var requestClient = manager.GetSessionQueueClient(requestQueueName);
 9             var session = requestClient.AcceptMessageSession();
10             var requestMessage = session.Receive();
11            
12             if (requestMessage != null)
13             {
14                 var receivedOrder = requestMessage.GetBody<SalesOrder>();
15                 Console.WriteLine("Receive message: " + requestMessage.MessageId + ", SalesOrder ID: " + receivedOrder.OrderID);
16 
17                 var responseMessage = new BrokeredMessage(receivedOrder);
18                 responseMessage.Properties.Add("Type", receivedOrder.GetType().ToString());
19                 responseMessage.ReplyToSessionId = ReplyToSessionId;
20                 responseMessage.MessageId = "ResponseOrderMessage001";
21                 responseMessage.SessionId = requestMessage.SessionId;
22                
23                 //发送回执消息
24                 var responseClient = manager.GetSessionQueueClient(requestMessage.ReplyTo);
25                 responseClient.Send(responseMessage);
26                 Console.WriteLine("Send receipt message: " + responseMessage.MessageId + ", SalesOrder ID: " + receivedOrder.OrderID);               
27             }
28         }
复制代码

Main方法中,启动两个工作线程:一个线程用于消息发送和接收回执消息,一个线程用于消息接收和发送消息回执。

因为涉及到Azure Messaging中队列的第一次创建,Azure Messaging是不支持多个请求同时创建同一个队列的,因此,我们两个线程间做一个简单的Task.Delay(3000).Wait();

复制代码
 1         static void Main(string[] args)
 2         {
 3             var sendTask = Task.Factory.StartNew(() => { SendMessage(); });
 4             Task.Delay(3000).Wait();
 5             var receiveTask = Task.Factory.StartNew(() => { ReceiveMessage(); });
 6 
 7             Task.WaitAll(sendTask, receiveTask);
 8 
 9             Console.ReadKey();           
10         }
复制代码

我们看看程序输出:

Azure 服务总线中的队列:

可以看出:Azure Messaging-ServiceBus Messaging 基于带会话的Queue/Topic、SessionId、ReplyTo属性来实现消息回执机制。

 

周国庆

2017/3/23

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 内容概要 《计算机试卷1》是一份综合性的计算机基础和应用测试卷,涵盖了计算机硬件、软件、操作系统、网络、多媒体技术等多个领域的知识点。试卷包括单选题和操作应用两大类,单选题部分测试学生对计算机基础知识的掌握,操作应用部分则评估学生对计算机应用软件的实际操作能力。 ### 适用人群 本试卷适用于: - 计算机专业或信息技术相关专业的学生,用于课程学习或考试复习。 - 准备计算机等级考试或职业资格认证的人士,作为实战演练材料。 - 对计算机操作有兴趣的自学者,用于提升个人计算机应用技能。 - 计算机基础教育工作者,作为教学资源或出题参考。 ### 使用场景及目标 1. **学习评估**:作为学校或教育机构对学生计算机基础知识和应用技能的评估工具。 2. **自学测试**:供个人自学者检验自己对计算机知识的掌握程度和操作熟练度。 3. **职业发展**:帮助职场人士通过实际操作练习,提升计算机应用能力,增强工作竞争力。 4. **教学资源**:教师可以用于课堂教学,作为教学内容的补充或学生的课后练习。 5. **竞赛准备**:适合准备计算机相关竞赛的学生,作为强化训练和技能检测的材料。 试卷的目标是通过系统性的题目设计,帮助学生全面复习和巩固计算机基础知识,同时通过实际操作题目,提高学生解决实际问题的能力。通过本试卷的学习与练习,学生将能够更加深入地理解计算机的工作原理,掌握常用软件的使用方法,为未来的学术或职业生涯打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值