Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I browse a Websphere MQ message without removing it?

I'm writing a .NET Windows Forms application that will post a message to a Websphere MQ queue and then poll a different queue for a response. If a response is returned, the application will partially process the response in real time. But the response needs to stay in the queue so that a daily batch job, which also reads from the response queue, can do the rest of the processing.

I've gotten as far as reading the message. What I haven't been able to figure out is how to read it without removing it.

Here's what I've got so far. I'm an MQ newbie, so any suggestions will be appreciated. And feel free to respond in C#.

Public Function GetMessage(ByVal msgID As String) As MQMessage
    Dim q = ConnectToResponseQueue()
    Dim msg As New MQMessage()
    Dim getOpts As New MQGetMessageOptions()
    Dim runThru = Now.AddMilliseconds(CInt(ConfigurationManager.AppSettings("responseTimeoutMS")))
    System.Threading.Thread.Sleep(1000) 'Wait for one second before checking for the first response'
    While True
        Try
            q.Get(msg, getOpts)
            Return msg
        Catch ex As MQException When ex.Reason = MQC.MQRC_NO_MSG_AVAILABLE
            If Now > runThru Then Throw ex
            System.Threading.Thread.Sleep(3000)
        Finally
            q.Close()
        End Try
    End While
    Return Nothing 'Should never reach here'
End Function

NOTE: I haven't verified that my code actually removes the message. But that's how I understand MQ to work, and that appears to be what's happening. Please correct me if that's not the default behavior.

like image 633
John M Gant Avatar asked Jun 24 '09 15:06

John M Gant


2 Answers

You need to open the queue with MQOO_BROWSE option. Then on your first read you do a GET using the MQGMO_BROWSE_FIRST option. Finally, your subsequent GET's should use the MQGMO_BROWSE_NEXT option.

Note: MQOO is MQ open options and MQGMO is MQ Get Message Options.

like image 198
mamboking Avatar answered Sep 20 '22 07:09

mamboking


For posterity's sake, here's a (I think) much improved version of the method based on mamboking and jmucchiello's answers.

Public Function GetMessage(ByVal correlID As Byte()) As MQMessage
    Dim waitInterval = CInt(ConfigurationManager.AppSettings("responseTimeoutMS"))
    Dim q As MQQueue = Nothing
    Try
        Dim msg As New MQMessage()
        Dim getOpts As New MQGetMessageOptions()
        q = ConnectToResponseQueue()
        msg.MessageId = MQC.MQMI_NONE
        msg.CorrelationId = correlID
        getOpts.MatchOptions = MQC.MQMO_MATCH_CORREL_ID
        getOpts.WaitInterval = waitInterval
        getOpts.Options = MQC.MQGMO_BROWSE_FIRST Or MQC.MQGMO_WAIT
        q.Get(msg, getOpts)
        Return msg
    Finally
        If q IsNot Nothing AndAlso q.IsOpen() Then q.Close()
    End Try
End Function
like image 36
John M Gant Avatar answered Sep 20 '22 07:09

John M Gant