一、MSMQ——消息的响应(响应队列)

  如果需要从接收程序中获得比确认消息更多的信息(消息确认参考二),就可以使用响应队列。响应队列类似于一般队列,但原始发生程序吧该队列用作接收程序,原始接收

程序把响应队列作用于发生程序。

  发送程序必须用 Message 类的 ResponseQueue 属性指定响应队列。在响应消息中,把 CorrelationId 属性设置为原始的消息ID,这样,客户端就知道该条应答属于哪条消息。

这类似于确认队列。响应消息用  MessageQueue 对象的 Send() 方法发送,MessageQueue 对象从 ResponseQueue  属性中返回。  

  当消息队列生成确认或报告消息时,它使用相关标识符属性来指定原始消息的消息标识符。 这样,相关标识符就可将报告或确认消息与原始消息关联起来。

  发送应用程序然后可以进行匹配的确认或与原始消息的报表通过使用CorrelationId属性来标识原始消息的Id属性。

  连接器应用程序还必须设置 CorrelationId 属性发送到原始消息的消息标识符的确认消息和报告的消息。

  当你的应用程序将响应消息发送到发送应用程序时,可以设置 CorrelationId 响应消息的原始消息的消息标识符的属性。 发送应用程序然后可以将响应消息与已发送的消息进行匹配。

/// <summary>
/// 消息队列
/// </summary>
private MessageQueue messageQueue
{
get
{
string path = ".\\private$\\temp";
if (MessageQueue.Exists(path))
{
//如果存在指定路径的消息队列,则获取
return new MessageQueue(path);
}
else
{
//不存在,则创建新的
return MessageQueue.Create(path);
}
}
} /// <summary>
/// 获取返回消息
/// </summary>
public void ReciveMessage()
{
while (true)
{
//Message.Receive()是同步进行的,如果队列中没有消息,会阻塞当前线程
Message message = messageQueue.Receive(); message.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
string msg = message.Body.ToString(); var responeMessage = new Message("responeMessage")
{
//原始消息id
CorrelationId = message.Id
};
message.ResponseQueue = GetResponseQueue();
//获取或设置一个值,该值指示发送方 ID 是否应附在消息中。
//message.AttachSenderId = true;
//发生响应消息
message.ResponseQueue.Send(responeMessage);
Console.WriteLine(msg);
}
}

获取响应消息,获得原消息id进行匹配

         /// <summary>
/// 获取响应队列
/// </summary>
/// <returns></returns>
public MessageQueue GetResponseQueue()
{
//路径
string path = ".\\private$\\ResponseQueue";
if (MessageQueue.Exists(path))
{
//如果存在指定路径的消息队列,则获取
return new MessageQueue(path);
}
else
{
//不存在,则创建新的
return MessageQueue.Create(path);
}
} /// <summary>
/// 获取返回队列消息
/// </summary>
public void ReciveResponseQueue()
{
while (true)
{
var myQueue = GetResponseQueue();
//设置将获取 CorrelationId 的MessageReadPropertyFilter设为TRUE
myQueue.MessageReadPropertyFilter.CorrelationId = true;
//Message.Receive()是同步进行的,如果队列中没有消息,会阻塞当前线程
Message message = myQueue.Receive(); message.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
string msg = message.Body.ToString();
//获取原始消息的Id
var _correlationId = message.CorrelationId;
message.ResponseQueue = GetResponseQueue(); Console.WriteLine(msg);
}
}

二、MSMQ——消息的确认

 

可以将MessageQueue对象设置为生成确认消息,能通知消息发送者消息是否已经成功传递。

有两种主要的确认类型:

·消息到达目标队列的确认

·目标应用程序从队列中检索到消息的确认

确认是通过向队列发送新消息来处理的。这种情况下,确认消息从目标队列发送到一个特殊类型的队列中:管理队列。确认消息不同于标准消息,因为它们不包含正文;在确认中,消息头中的信息最重要。

这里以一个示例来演示一下:

(一)新建管理队列

private MessageQueue CreateAdminQueue()

{

string trPath = @".\Private$\selfAdminQueue";

MessageQueue _queue;

if (!MessageQueue.Exists(trPath))

return MessageQueue.Create(trPath);

_queue = new MessageQueue(trPath);

return _queue;

}

(二)传递消息

public void SendConfirmMessage(string strMsg)

{

MessageQueue _queue = CreateQueue();

Message _message = new Message(strMsg);

_message.AdministrationQueue = CreateAdminQueue();

_message.AcknowledgeType =

AcknowledgeTypes.PositiveReceive

| AcknowledgeTypes.PositiveArrival;

_queue.Send(_message);

}

·设置AdminstrationQueue的属性。这个属性是用来设置和获取接收消息队列的确认消息的队列。

·设置确认消息属性AcknowledgeType。这个属性是用来设置和获取返回给发送方消息确认的类型,它是个枚举类型。枚举值:

PositiveArrival

一个掩码,用于在原始消息到达队列时请求肯定确认。

PositiveReceive

一个掩码,用于在成功从队列检索到原始消息时请求肯定确认。

NegativeReceive

一个掩码,用于当未能从队列接收原始消息时请求否定确认。

None

一个掩码,用于请求不发送任何确认消息(无论是肯定的还是否定的)。

NotAcknowledgeReachQueue

一个掩码,用于在原始消息不能到达队列时请求否定确认。当到达队列时间计时器过期时或不能对消息进行身份验证时,可能请求否定确认。

NotAcknowledgeReceive

一个掩码,用于当发生错误时请求否定确认,防止在其接收时间计时器过期前从队列接收原始消息。

FullReachQueue

一个掩码,用于在原始消息到达队列时请求肯定确认,或者用于到达队列时间计时器过期后请求否定确认,或者用于不能对原始消息进行身份验证时请求否定确认。

FullReceive

一个掩码,用于在接收时间计时器过期前从队列收到原始消息时请求肯定确认,否则请求否定确认。

(三)接收方

public string GetNormalMessage()

{

MessageQueue _queue = CreateQueue();

_queue.Formatter =

new XmlMessageFormatter(new Type[] { typeof(string) });

Message _message = _queue.Receive();

return _message.Id;

}

接收消息正常接收。然后得到消息的Id,通过Id来获取在管理队列中的管理消息的信息

(四)管理队列消息

public void GetAcknowledgmentMessage(string strMsgId)

{

MessageQueue _queue = CreateAdminQueue();

_queue.MessageReadPropertyFilter.CorrelationId = true;

_queue.MessageReadPropertyFilter.Acknowledgment = true;

try

{

while (_queue.PeekByCorrelationId(strMsgId) != null)

{

Message myAcknowledgmentMessage =

_queue.ReceiveByCorrelationId(strMsgId);

Console.WriteLine("Correlation Id: "

+ myAcknowledgmentMessage.CorrelationId.ToString());

Console.WriteLine("Id: "

+ myAcknowledgmentMessage.Id.ToString());

Console.WriteLine("Acknowledgment Type: "

+ myAcknowledgmentMessage.Acknowledgment.ToString());

}

}

catch

{ }

}

通过消息标识来检索管理队列,检索成功打印信息。确认类型Acknowledgment用于指定尝试的消息传递的结果。它是个枚举:

None

该消息不是确认消息。

AccessDenied

一个否定到达确认,它指示发送应用程序不具有将消息发送到目标队列所需的权限。

BadDestinationQueue

一个否定到达确认,它指示目标队列不可用于发送应用程序。

BadEncryption

一个否定到达确认,它指示目标队列管理器未能解密私有消息。

BadSignature

一个否定到达确认,它指示原始消息的数字签名无效并且未能由消息队列进行身份验证。

CouldNotEncrypt

一个否定到达确认,它指示源队列管理器未能加密私有消息。

HopCountExceeded

一个否定到达确认,它指示已超出了原始消息的跳数(跳数指示中间服务器的数目)。

NotTransactionalQueue

一个否定到达确认,它指示已将事务性消息发送到非事务性队列。

NotTransactionalMessage

一个否定到达确认,它指示非事务性消息被发送到了事务性队列。

Purged

一个否定到达确认,它指示消息在到达其目标队列前已被清除。

QueueDeleted

一个否定读取确认,它指示在可以读取消息前队列已被删除。

QueueExceedMaximumSize

一个否定到达确认,它指示原始消息因其目标队列已满而未被传送。

QueuePurged

一个否定读取确认,它指示在可以读取消息前队列已被清除。

ReachQueue

一个肯定到达确认,它指示原始消息已到达其目标队列。

ReachQueueTimeout

一个否定到达确认,它指示在原始消息可到达目标队列前到达队列时间计时器或接收时间计时器已过期。

ReceiveTimeout

一个否定读取确认,它指示在其接收时间计时器过期前没有从队列接收原始消息。

Receive

一个肯定读取确认,它指示原始消息已由接收应用程序接收

(五)流程

·当向消息队列传递消息时,同时向管理队列传递了消息(当消息队列收到消息后,管理队列中也会收到消息)。此时的消息是:消息已经到达消息队列。(在管理队列中的消息是不带包体正文的,所以说头最重要。)

·当从消息队列中接收到消息后(此时消息的标识已经读出),消息队列消息就会清空(Revceive的)。然后在管理队列中就会再多一条管理消息,来标示:消息已经被接收。

·当处理管理队列消息时,会按消息标识来处理管理队列消息。

MSMQ—确认队列和响应队列的更多相关文章

  1. PHP电商订单自动确认收货redis队列

    一.场景 之前做的电商平台,用户在收到货之后,大部分都不会主动的点击确认收货,导致给商家结款的时候,商家各种投诉,于是就根据需求,要做一个订单在发货之后的x天自动确认收货.所谓的订单自动确认收货,就是 ...

  2. 三次握手 四次握手 原因分析 TCP 半连接队列 全连接队列

    小结 1. 三次握手的原因:保证双方收和发消息功能正常: [生活模型] "请问能听见吗""我能听见你的声音,你能听见我的声音吗" [原理]A先对B:你在么?我在 ...

  3. RabbitMQ使用 prefetch_count优化队列的消费,使用死信队列和延迟队列实现消息的定时重试,golang版本

    RabbitMQ 的优化 channel prefetch Count 死信队列 什么是死信队列 使用场景 代码实现 延迟队列 什么是延迟队列 使用场景 实现延迟队列的方式 Queue TTL Mes ...

  4. Java多线程:队列与阻塞队列

    1. 什么是阻塞队列 阻塞队列(BlockingQueue)是 Java 5 并发新特性中的内容,阻塞队列的接口是 java.util.concurrent.BlockingQueue,它提供了两个附 ...

  5. 为什么使用消息队列?消息队列有什么优点和缺点?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么优点和缺点?

    面试题 为什么使用消息队列? 消息队列有什么优点和缺点? Kafka.ActiveMQ.RabbitMQ.RocketMQ 都有什么区别,以及适合哪些场景? 面试官心理分析 其实面试官主要是想看看: ...

  6. RabbitMQ六种队列模式-简单队列模式

    前言 RabbitMQ六种队列模式-简单队列 [本文]RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...

  7. RabbitMQ从零到集群高可用(.NetCore5.0) - 死信队列,延时队列

    系列文章: RabbitMQ从零到集群高可用(.NetCore5.0) - RabbitMQ简介和六种工作模式详解 RabbitMQ从零到集群高可用(.NetCore5.0) - 死信队列,延时队列 ...

  8. RabbitMQ 入门系列:10、扩展内容:延时队列:延时队列插件及其有限的适用场景(系列大结局)。

    系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...

  9. C ~ 链式队列与循环队列

          此处的链式与循环队列可以应用于BFS和树的层序遍历.下面是对其结构和基本操作的程序描述. 1.循环队列 解决循环队列的队空和队满的方法: [1].增加一个参数count,用来记录数组中当前 ...

随机推荐

  1. Netty 线程模型

    一.线程模型概述 线程模型表明了代码的执行方式.从最开始的使用单线程,后来出现了多线程,之后是线程池.当有要执行的任务时,任务会被传到线程池,从线程池中获得空闲的线程来执行任务,执行完了后会将线程返回 ...

  2. jquery: 获取当前天加减一天

    // 对Date的扩展,将 Date 转化为指定格式的String // 月(M).日(d).小时(h).分(m).秒(s).季度(q) 可以用 1-2 个占位符, // 年(y)可以用 1-4 个占 ...

  3. 如何实现Proxifier只代理部分程序

    转载自:https://jingyan.baidu.com/article/48b558e35e12f97f38c09a28.html 小编工作时上外网要通过局域网内其他人开代理,然后通过IE代理上网 ...

  4. PRBS

    PRBS是Pseudo Random Binary Sequence的缩写,即“伪随机二进制序列”的意思.PRBS码具有“随机”特性,是因为在PRBS码流中,二进制数“0”和“1”是随机出现的,但是它 ...

  5. Optaplanner规划引擎的工作原理及简单示例(1)

    在之前的文章中,老猿已介绍过APS及规划的相关内容,也对Optaplanner相关的概念和一些使用示例进行过介绍,接下来的文章中,我会自己做一个规划小程序 - 一个关于把任务分配到不同的机台上进行作来 ...

  6. 京东饭粒捡漏V1.1.0

    20180624 更新 V1.1.01.解决进程残留问题:2.加入急速下单模式: 功能介绍1.京东商城专用,支持饭粒模式下单,自己获得京豆返利 2.捡漏模式:帮助用户监控抢购商品,有库存的时候进行抢单 ...

  7. ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (13)解答

    我在使用mysqll客户端连接我的mysql服务器的时候,出现了上述的问题.我的操作系统是ubuntu,安装版本是对应的64位服务器.我的服务器的启动方式是sudo service mysql sta ...

  8. myeclipse2018安装教程(附下载地址)

    这两天在网上找myeclipse2018的安装包和破解工具,很分散,并且破解失败很多,现在总结下 myeclipse2018下载地址: https://pan.baidu.com/s/1NV7cAsN ...

  9. 用yum快速搭建LAMP平台

    实验环境: [root@nmserver-7 html]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) [root@nms ...

  10. 开源邮件系统Zimbra Collaboration – Open Source Edition

    https://www.zimbra.com/downloads/zimbra-collaboration-open-source/ Zimbra Collaboration – Open Sourc ...