可以将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的)。然后在管理队列中就会再多一条管理消息,来标示:消息已经被接收。
·当处理管理队列消息时,会按消息标识来处理管理队列消息。