具有不同消息类型的消息队列

时间:2012-05-29 11:55:37

标签: c# msmq

我正在调查Microsoft Message Queues以进行进程间跨网络消息传递。但是当我收到消息时,我不知道先验我得到了什么类型的对象,所以代码

queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(Wibble) });

无法在之前应用我收到消息,因为我不知道它是否是Wibble。那么我如何收到不同的消息类型呢?

4 个答案:

答案 0 :(得分:12)

您已经在使用接受数组类型的XmlMessageFormatter的构造函数重载。因此,只需将所有类型的类型添加到该数组中,而不仅仅是一种类型。

queue.Formatter = new XmlMessageFormatter(new Type[] {
    typeof(Wibble),
    typeof(Fleem),
    typeof(Boo)
});

来自TargetTypes

  

在邮件正文中序列化的实例必须符合 类型数组中表示的模式之一。当您使用Receive方法读取消息时,该方法将创建与所标识的模式对应的类型的对象,并将消息正文读入其中。

(强调补充)

答案 1 :(得分:3)

您可能会考虑不将对象存储在MSMQ消息中,而是在可能的情况下引用它的持久位置。 MSMQ在消息队列上具有有限的空间,因此最小的消息是最好的。

如果您不能这样做,您可以使用您喜欢的任何序列化程序直接将对象序列化为消息BodyStream。然后存储类型名称,可能最好在消息标签中。

与此非常相似的东西(在这里划掉它,在这台计算机上没有IDE)将它放入,并且在出路时采取了类似的行动:

public void FormatObject(object toFormat, Message message)
{
    var serializer = new XmlSerializer(toFormat.GetType());
    var stream = new MemoryStream();
    serializer.Serialize(toFormat, stream);

    //don't dispose the stream
    message.BodyStream = stream;
    message.Label = toFormat.GetType().AssemblyQualifiedName;
}

答案 2 :(得分:1)

在MSMQ上运行的大量错误信息主要是因为Microsoft文档在如何正确设计消息发送接收方面非常稀少。我有两本关于这个主题的MSMQ书籍,我仍然在互联网上寻找合理的设计。

因此,这些引用都没有说队列要求有一种消息类型。这将使PeakMessage和变体变得不必要甚至是愚蠢的。微软的文档含糊不清,但我在那里工作过,而且从不愚蠢。

使用CLSID作为标识符一直存在令人恼火的建议,这种做法令人烦恼地短视。如何尝试在LABEL中嵌入消息类型???然后使用PeadMessage运行队列,直到找到明确针对您的特定队列的消息,并使用消息类型,您可以使用该消息类型格式化消息属性以在第一次尝试时正确接收消息???

我知道这会产生一个复杂的代码集,但你宁愿不这样做吗?或者你真的会尝试实现上面的响应者的建议谁暗示如果你有一个200个用户的系统有200种消息类型,他们应该创建80,000个队列来管理所有一对一的要求?有些人只是不认为这些事情。

答案 3 :(得分:0)

评论中注明joocer:对不同的消息类型使用不同的队列。

或者,您可以同意消息发送者所有消息都是XML(任何不解析为XML的内容都被拒绝)。然后还同意XML模式的一些基础知识:带有消息类型(和版本)的头元素。

然后处理(通过串行器自己)到内部类型。

当然,在许多情况下 - 反序列化没有实际好处 - 只需根据需要阅读XML的内容。