2012-05-29 6 views
9

Я изучаю очереди сообщений Microsoft для выполнения межсетевых межсетевых сообщений. Но когда я получаю сообщение, я не знаю априори какой тип объекта я получаю, поэтому кодОчереди сообщений с разными типами сообщений

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

не может быть применен перед тем я получаю сообщение, потому что я дон «Не знаю, это ли это смешок. Итак, как мне получить разные типы сообщений?

+3

+1 для 'Wibble' – cjk

+0

Две возможности приходят на ум; 1) иметь одну очередь для Wibbles и одну очередь для Gizmos; 2) попытайтесь объединиться с Wibble, если это не удается, попробуйте применить к объекту Gizmo – joocer

+0

typeof (Object) и отобразить классы на объект до тех пор, пока он не подходит? – sinni800

ответ

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; 
} 
+0

Я сделал что-то подобное с RabbitMQ. Я использовал заголовок сообщения, чтобы указать тип объекта, сериализованного в теле сообщения. –

+0

@tallseth: В конце приемника, как мы это делаем? Сравниваем ли мы метку с типом всех классов, которые у нас есть? Это может быть несколько –

+0

Относительно комментария ** // не удаляйте поток **. Когда поток удаляется тогда? – bornfromanegg

9

Вы уже используете перегрузку конструктора для XmlMessageFormatter, который принимает массив типов. Поэтому просто добавьте все типы типов, которые вы ожидаете получить в этом массиве, а не только один тип.

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

От TargetTypes:

экземпляр сериализовать в теле сообщения должно соответствовать одному из схем, представленных в массиве типа. Когда вы читаете сообщение с использованием метода Receive, метод создает объект типа, который соответствует идентифицированной схеме, и читает тело сообщения в нем.

(Выделено)

0

Как joocer отмечает в комментарии: использование другая очередь для разных типов сообщений.

В качестве альтернативы вы можете согласиться с отправителями сообщений, что все сообщения будут XML (все, что не анализируется, поскольку XML отклоняется). Затем также согласуются некоторые основы XML-схемы: элемент заголовка с типом сообщения (и версией).

Затем обработайте (самостоятельно через сериализатор) во внутренний тип.

Конечно, во многих случаях, где нет реальной выгоды для десериализации, просто прочитайте содержимое XML по мере необходимости.

1

В MSMQ существует много дезинформации, прежде всего потому, что документация Microsoft пугающе решается, как правильно настроить отправку сообщений. У меня есть обе книги MSMQ, изданные по этому вопросу, и я все еще ищу разумные проекты в Интернете.

Таким образом, ни одна из этих ссылок не говорит о том, что существует один тип сообщения для требования к очереди.И это сделало бы PeakMessage и варианты ненужными и даже глупыми. Microsoft неясна и сложна в своей документации, но я работал там, и они никогда не были глупыми.

Существует постоянное раздражающее предложение использовать CLSID в качестве идентификатора, практика, которая досадно коротко прицеливается. Как насчет попытки вставить тип сообщения в LABEL ??? Затем используйте PeadMessage для запуска очереди, пока не найдете сообщение, явно предназначенное для вашей конкретной очереди, и с типом сообщения, которое можно использовать для форматирования свойств сообщения для правильного получения сообщения с первой попытки ???

Я знаю, что это делает сложный набор кода, но вы бы предпочли обойтись? Или вы действительно попытаетесь реализовать предложение ответчика выше, который подразумевает, что если у вас есть система из 200 пользователей с 200 типами сообщений, они должны создать 80 000 очередей для управления всеми требованиями к одному? Некоторые люди просто не думают об этом.