Чтение сообщений MSMQ из службы Windows VB.net - PullRequest
0 голосов
/ 02 февраля 2010

Как я могу прочитать сообщения MSMQ из службы Windows VB.net, написанной на VB.net 2008. Сообщения в MQ содержат данные XML. Мне нужно прочитать этот XML, используя LinQ to XML, проверить XSD.

Я был бы очень признателен, если бы вы могли направить меня к образцу

Спасибо

Ответы [ 2 ]

4 голосов
/ 02 февраля 2010

Я бы предложил посмотреть WCF , используя MsmqIntegrationBinding . Я недавно сделал то же самое (за исключением использования netMsmqBinding, так как я не интегрировался с уже существующей системой), и это сработало очень хорошо. Для образцов, вы должны посмотреть WCF Samples , предоставленный Microsoft.

0 голосов
/ 24 марта 2014

Я только что написал эту точную вещь, но поскольку я связал свои сообщения с конкретным классом, проверка выполняется автоматически. Напомним, что когда вы отправляете объект в MSMQ в качестве сообщения, он все еще «сводится» к XML ... Так что, я думаю, я делаю то, что делал бы XSD, но гораздо более простым способом.

Служебная часть, вероятно, здесь неактуальна, но я использую службы как отправители, получатели и анализаторы для MSMQ.

Вот как я управляю объектом в MSMQ:

Чтобы понять чтение, вам нужно понять, как отправить объект (XML, класс, что угодно):

Примечание. SyslogEntry - это POCO с атрибутами для каждой части обычного сообщения syslog / UDP514. В этом классе нет логики.

Public Sub SendMessage(syslogEntry As SyslogEntryLibrary.syslog.SyslogEntry, qPath As String)
    Try
        ' Connect to a queue on the local computer. 
        Me.TheQ = New MessageQueue(qPath)
        ' make all messages recoverable
        Me.TheQ.DefaultPropertiesToSend.Recoverable = True
        ' Create a new message. 
        Me.MsgTo = New Message(syslogEntry, New XmlMessageFormatter(New Type() {GetType(SyslogEntryLibrary.syslog.SyslogEntry)}))
        With Me.MsgTo
            .AcknowledgeType = AcknowledgeTypes.PositiveReceive Or AcknowledgeTypes.PositiveArrival
            ' .Body = syslogEntry
            .Priority = MessagePriority.Normal
        End With
        ' set what will be sent with message...
        TheQ.MessageReadPropertyFilter.ArrivedTime = True
        TheQ.MessageReadPropertyFilter.SentTime = True
        TheQ.MessageReadPropertyFilter.CorrelationId = True
        TheQ.MessageReadPropertyFilter.Id = True
        TheQ.Formatter = New XmlMessageFormatter(New Type() {GetType(SyslogEntryLibrary.syslog.SyslogEntry)})
        TheQ.Send(MsgTo)
    Catch ex As Exception
        [...]
    End Try
    Return

Единственная интересная часть вышесказанного - это:

Me.MsgTo = Новое сообщение (syslogEntry, New XmlMessageFormatter (New Type () {GetType (SyslogEntryLibrary.syslog.SyslogEntry)}))

Я говорю MSMQ точный формат, который примет отправленное сообщение, чтобы оно могло разбить его на XML для меня в теле сообщения. О, и еще одна вещь, я стараюсь не создавать экземпляры каких-либо объектов при отправке или получении сообщений (предпочитая повторно использовать переменную уровня класса) исключительно из соображений скорости и ресурсов. Вот почему вы видите такие вещи, как «Me.TheQ», «Me.MsgTo» и т. Д. Не знаю, имеет ли это значение, но это практика / привычка, которую я придерживался годами ... :)

В любом случае, типичное сообщение этого класса выглядит так:

enter image description here

Вы можете увидеть имя класса и некоторые определения схемы в теле. Я не имею к этому никакого отношения - все это сделано для меня (с отражением):)

Итак, теперь, когда мое сообщение (действительно экземпляр класса) находится в очереди, пришло время получить его из другой программы (может быть, из службы?) И восстановить это!

Public Function ReceiveMessage(qPath As String) As SyslogEntryLibrary.syslog.SyslogEntry
    Dim sysEvent As SyslogEntryLibrary.syslog.SyslogEntry = Nothing
    Try
        ' Connect to the a queue on the local computer. 
        Me.rcvQueue = New MessageQueue(qPath)
        Me.rcvQueue.MessageReadPropertyFilter.CorrelationId = True
        ' Set the formatter to indicate body contains a SyslogEntry instance
        Me.rcvQueue.Formatter = New XmlMessageFormatter(New Type() {GetType(SyslogEntryLibrary.syslog.SyslogEntry)})
        ' Receive and format the message.  
        Dim myMessage As Message = Me.rcvQueue.Receive()
        sysEvent = CType(myMessage.Body, SyslogEntryLibrary.syslog.SyslogEntry) 
    Catch ex As InvalidOperationException
        [...]
    Catch ex As Exception
        [...]
    End Try
    Return sysEvent
End Function 'ReceiveMessage

Так же, как и раньше, магия происходит в следующих строках:

Me.rcvQueue.Formatter = New XmlMessageFormatter (New Type () {GetType (SyslogEntryLibrary.syslog.SyslogEntry)})

Dim myMessage As Message = Me.rcvQueue.Receive ()

sysEvent = CType (myMessage.Body, SyslogEntryLibrary.syslog.SyslogEntry)

Я видел примеры, которые используют XML в качестве тела и даже просто строку, поэтому я уверен, что вы можете поиграть с этим, как считаете нужным.

Тем не менее, не понимая, что вы пытаетесь сделать, вы простите меня, если я предложу вам придерживаться POCO в своей бизнес-логике и позволить инструментам более низкого уровня, таким как MSMQ, сделать все форматирование XML за вас. Одна вещь, я ненавижу делать это, писать XML в коде «вручную». :)

Надеюсь, это даст вам несколько идей!

...