ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » IBM MQ API Support » iMessageConsumer - how does one reply to the message

Post new topic  Reply to topic Goto page 1, 2  Next
 iMessageConsumer - how does one reply to the message « View previous topic :: View next topic » 
Author Message
JeffTheDotNetGuy
PostPosted: Fri Aug 21, 2009 7:17 am    Post subject: iMessageConsumer - how does one reply to the message Reply with quote

Novice

Joined: 21 Aug 2009
Posts: 10

I am missing something obvious (obviously).

I have created an application that posts messages to a queue, and I have a Windows service that uses the iMessageConsumer interface (and a call to .ReceiveNoWait) to "catch" the message. That part works great... but once I have the received the message, I can't see anything anywhere about how I send to back a reply.

The application that posted the message with a call to IBM.XMS.Requestor.Request method just sits there and twists waiting for a reply that never comes.
Back to top
View user's profile Send private message
JeffTheDotNetGuy
PostPosted: Fri Aug 21, 2009 7:21 am    Post subject: Reply with quote

Novice

Joined: 21 Aug 2009
Posts: 10

Hopefully my name implied it, but I'm using the ia9h support pack in .NET for this project.
Back to top
View user's profile Send private message
Vitor
PostPosted: Fri Aug 21, 2009 7:25 am    Post subject: Re: iMessageConsumer - how does one reply to the message Reply with quote

Grand High Poobah

Joined: 11 Nov 2005
Posts: 26093
Location: Texas, USA

JeffTheDotNetGuy wrote:
I can't see anything anywhere about how I send to back a reply.


Send a message that's configured as a reply? Using the details from the request?
_________________
Honesty is the best policy.
Insanity is the best defence.
Back to top
View user's profile Send private message
JeffTheDotNetGuy
PostPosted: Fri Aug 21, 2009 7:26 am    Post subject: Reply with quote

Novice

Joined: 21 Aug 2009
Posts: 10

Additional details:

after I have received the message in the Windows service, if I .Acknowledge it, I watch my "Open Output Count" in the queue go up by 1, as though it's starting to reply or something.

So close... yet so far.

Shutting down my solution, all "Open Input Count"s zero out, but Open Output Counts stay. When I "Browse" the messages with the MQ Explorer, there are none.
Back to top
View user's profile Send private message
Vitor
PostPosted: Fri Aug 21, 2009 7:31 am    Post subject: Reply with quote

Grand High Poobah

Joined: 11 Nov 2005
Posts: 26093
Location: Texas, USA

Ok, so my .NET is only slightly better than my Java, but AFAIK the .Acknowledge is not doing what you think it is. If you're trying to send a reply in the WMQ sense then it's actually a separate message. I don't think you actually want to be fiddling with the auto response.

Also is ReceiveNoWait the right choice? Why that method?
_________________
Honesty is the best policy.
Insanity is the best defence.
Back to top
View user's profile Send private message
Vitor
PostPosted: Fri Aug 21, 2009 7:33 am    Post subject: Reply with quote

Grand High Poobah

Joined: 11 Nov 2005
Posts: 26093
Location: Texas, USA

JeffTheDotNetGuy wrote:
Shutting down my solution, all "Open Input Count"s zero out, but Open Output Counts stay. When I "Browse" the messages with the MQ Explorer, there are none.


That just means the queue isn't being closed properly, because you're using .Acknowledge incorrectly.
_________________
Honesty is the best policy.
Insanity is the best defence.
Back to top
View user's profile Send private message
JeffTheDotNetGuy
PostPosted: Fri Aug 21, 2009 7:34 am    Post subject: Reply with quote

Novice

Joined: 21 Aug 2009
Posts: 10

Thanks, Vitor.

Let me try your suggestion again, but I thought I did that, and the attempt to send the return message hung on the Windows Service side... of all things, waiting for a response.

.ReceiveNoWait is the correct call, since that method simply pulls the next available message from the queue, or returns Nothing if there is nothing there.

The other methods involve setting timeouts which won't be necessary in this case.
Back to top
View user's profile Send private message
Vitor
PostPosted: Fri Aug 21, 2009 7:39 am    Post subject: Reply with quote

Grand High Poobah

Joined: 11 Nov 2005
Posts: 26093
Location: Texas, USA

JeffTheDotNetGuy wrote:
.ReceiveNoWait is the correct call, since that method simply pulls the next available message from the queue, or returns Nothing if there is nothing there.

The other methods involve setting timeouts which won't be necessary in this case.


I do know that. It's just unusual to be able to be so black & white on message availability. Typically applications have some lattitude.

But it's your solution. I applaude your ability to be certain a message will be available, or not.
_________________
Honesty is the best policy.
Insanity is the best defence.
Back to top
View user's profile Send private message
JeffTheDotNetGuy
PostPosted: Fri Aug 21, 2009 7:44 am    Post subject: Reply with quote

Novice

Joined: 21 Aug 2009
Posts: 10

OK... well... second time is the charm.

It might help if I posted the code.

I tried something different this time... I took the original message I received, and just changed it into a reply message, and sent it, and the client did unlock and "catch" my reply.

However, the Windows Service locks on that call waiting for a reply of it's own (even though the type is being set to Response Message). See below:


Code:

    Public Sub ProcessQueueMessages()
        Try
            If oFactory Is Nothing Then
                oFactory = IBM.XMS.XMSFactoryFactory.GetInstance(IBM.XMS.XMSC.CT_WMQ)
            End If
            If oConnectionFactory Is Nothing Then
                oConnectionFactory = oFactory.CreateConnectionFactory
                oConnectionFactory.SetStringProperty(IBM.XMS.XMSC.WMQ_HOST_NAME, "TX-JCPC691")
                oConnectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_PORT, 1414)
                oConnectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_CONNECTION_MODE, 1)
                oConnectionFactory.SetStringProperty(IBM.XMS.XMSC.WMQ_QUEUE_MANAGER, "TestQueueManager")
                oConnectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_BROKER_VERSION, 0)

            End If
            If oConnection Is Nothing Then
                oConnection = oConnectionFactory.CreateConnection
                oConnection.Start()
            End If
            If oTopic Is Nothing Then
                oTopic = oFactory.CreateQueue("TestQueue")

            End If

            Dim oSession As IBM.XMS.ISession = oConnection.CreateSession(False, IBM.XMS.AcknowledgeMode.AutoAcknowledge)
            Dim oProcessor As IBM.XMS.IMessageConsumer

            oProcessor = oSession.CreateConsumer(oTopic)
            Dim oCurrMessage As IBM.XMS.IMessage
            oCurrMessage = oProcessor.ReceiveNoWait

            While Not oCurrMessage Is Nothing
                Dim oReplier As New IBM.XMS.Requestor(oSession, oCurrMessage.JMSReplyTo)

                With CType(oCurrMessage, IBM.XMS.ITextMessage)
                    .JMSType = IBM.XMS.MQC.MQMT_REPLY
                    .JMSDestination = oCurrMessage.JMSReplyTo
                    .JMSReplyTo = Nothing
                    .ClearBody()
                    .Text = "Yo back at you!"
                End With

                oReplier.Request(oCurrMessage)

                CloseAndDispose(oReplier)

                oCurrMessage = oProcessor.ReceiveNoWait

            End While

            CloseAndDispose(oProcessor)
            oProcessor = Nothing

            CloseAndDispose(oSession)
            oSession = Nothing

        Catch ex As Exception
            Dispose(oTopic)
            oTopic = Nothing
            CloseAndDispose(oConnection)
            oConnection = Nothing
            oConnectionFactory = Nothing
            oFactory = Nothing
        End Try

    End Sub


Last edited by JeffTheDotNetGuy on Fri Aug 21, 2009 11:36 am; edited 1 time in total
Back to top
View user's profile Send private message
JeffTheDotNetGuy
PostPosted: Fri Aug 21, 2009 7:47 am    Post subject: Reply with quote

Novice

Joined: 21 Aug 2009
Posts: 10

This function (above) is called by an exclusive timer that has a 100 millisecond interval, so if there is ever any error, all of the objects get destroyed and recreated 100 milliseconds later.

Do I have to .Acknowledge the reply?
Back to top
View user's profile Send private message
Vitor
PostPosted: Fri Aug 21, 2009 8:01 am    Post subject: Reply with quote

Grand High Poobah

Joined: 11 Nov 2005
Posts: 26093
Location: Texas, USA

JeffTheDotNetGuy wrote:
This function (above) is called by an exclusive timer that has a 100 millisecond interval, so if there is ever any error, all of the objects get destroyed and recreated 100 milliseconds later.


At the risk of sounding like a cracked record, why are you using ReceiveNoWait and a timer rather than the more efficient ReceiveWait?

JeffTheDotNetGuy wrote:
Do I have to .Acknowledge the reply?


Not if the client has responded to the reply. Sounds like something else is going on with the service.
_________________
Honesty is the best policy.
Insanity is the best defence.
Back to top
View user's profile Send private message
JeffTheDotNetGuy
PostPosted: Fri Aug 21, 2009 8:08 am    Post subject: Reply with quote

Novice

Joined: 21 Aug 2009
Posts: 10

What is the difference? Either way, don't I get a message that I need to reply to?
Back to top
View user's profile Send private message
JeffTheDotNetGuy
PostPosted: Fri Aug 21, 2009 8:19 am    Post subject: Reply with quote

Novice

Joined: 21 Aug 2009
Posts: 10

OK, Vitor.

I changed the function to wait indefinitely for a message. The resulting behavior was the same.

The client is catching the response, but the server hangs waiting for a response to it's response.

I wish the API exposed more than this one way of sending a message, because it's behaving exactly like the documentation says (sending a message and waiting for a response).

I'm starting to think IBM did not intend for people to use this library to create server-side queue processors.



Code:

    Public Sub ProcessQueueMessages2()
        Try
            If oFactory Is Nothing Then
                oFactory = IBM.XMS.XMSFactoryFactory.GetInstance(IBM.XMS.XMSC.CT_WMQ)
            End If
            If oConnectionFactory Is Nothing Then
                oConnectionFactory = oFactory.CreateConnectionFactory
                oConnectionFactory.SetStringProperty(IBM.XMS.XMSC.WMQ_HOST_NAME, "TX-JCPC691")
                oConnectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_PORT, 1414)
                oConnectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_CONNECTION_MODE, 1)
                oConnectionFactory.SetStringProperty(IBM.XMS.XMSC.WMQ_QUEUE_MANAGER, "TestQueueManager")
                oConnectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_BROKER_VERSION, 0)

            End If
            If oConnection Is Nothing Then
                oConnection = oConnectionFactory.CreateConnection
                oConnection.Start()
            End If
            If oTopic Is Nothing Then
                oTopic = oFactory.CreateQueue("TestQueue")

            End If

            Dim oSession As IBM.XMS.ISession = oConnection.CreateSession(False, IBM.XMS.AcknowledgeMode.AutoAcknowledge)
            Dim oProcessor As IBM.XMS.IMessageConsumer

            oProcessor = oSession.CreateConsumer(oTopic)
            Dim oCurrMessage As IBM.XMS.IMessage
            oCurrMessage = oProcessor.Receive(0)

            While Not oCurrMessage Is Nothing
                Dim oReplier As New IBM.XMS.Requestor(oSession, oCurrMessage.JMSReplyTo)

                With CType(oCurrMessage, IBM.XMS.ITextMessage)
                    .ClearBody()
                    .JMSType = IBM.XMS.MQC.MQMT_REPLY
                    .JMSDestination = oCurrMessage.JMSReplyTo
                    .JMSReplyTo = Nothing
                    .Text = "Yo back at you!"
                End With

                oReplier.Request(oCurrMessage)

                CloseAndDispose(oReplier)

                oCurrMessage = oProcessor.ReceiveNoWait

            End While

            CloseAndDispose(oProcessor)
            oProcessor = Nothing

            CloseAndDispose(oSession)
            oSession = Nothing

        Catch ex As Exception
            Dispose(oTopic)
            oTopic = Nothing
            CloseAndDispose(oConnection)
            oConnection = Nothing
            oConnectionFactory = Nothing
            oFactory = Nothing
        End Try

    End Sub
[/code]

Last edited by JeffTheDotNetGuy on Fri Aug 21, 2009 11:35 am; edited 1 time in total
Back to top
View user's profile Send private message
JeffTheDotNetGuy
PostPosted: Fri Aug 21, 2009 11:05 am    Post subject: Reply with quote

Novice

Joined: 21 Aug 2009
Posts: 10

OK... I just wanted to come back and update this thread in case any other newb (like me) might stumble across this.

It took cracking the library open with .NET Reflector to understand what was happening.

Under the hood, what the Requester object does is actually create a temporary queue, and it is that queue that you must return the reply on. My problem in my previous examples was that I was creating my return message from the wrong queue (it needs to be that temporary queue).

I did eventually find the oSession.CreateProducer (and that's where you want to slap yourself because it's right there in the sample projects). Vitor's advance was also correct (of course) (except for the part about *how* I was getting the message): a reply to a message is actually a separate message.

So newbs, notice below that I build my producer object off of the message's.JSFReplyTo object, and all is well with the world.




Code:

    Public Sub ProcessQueueMessages()
        Try

            If oFactory Is Nothing Then
                oFactory = IBM.XMS.XMSFactoryFactory.GetInstance(IBM.XMS.XMSC.CT_WMQ)
            End If

            If oConnectionFactory Is Nothing Then
                oConnectionFactory = oFactory.CreateConnectionFactory
                oConnectionFactory.SetStringProperty(IBM.XMS.XMSC.WMQ_HOST_NAME, "TX-JCPC691")
                oConnectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_PORT, 1414)
                oConnectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_CONNECTION_MODE, 1)
                oConnectionFactory.SetStringProperty(IBM.XMS.XMSC.WMQ_QUEUE_MANAGER, "TestQueueManager")
                oConnectionFactory.SetIntProperty(IBM.XMS.XMSC.WMQ_BROKER_VERSION, 0)
            End If

            If oConnection Is Nothing Then
                oConnection = oConnectionFactory.CreateConnection
                oConnection.Start()
            End If

            If oTopic Is Nothing Then
                oTopic = oFactory.CreateQueue("TestQueue")
            End If

            Dim oSession As IBM.XMS.ISession = oConnection.CreateSession(False, IBM.XMS.AcknowledgeMode.AutoAcknowledge)
            Dim oProcessor As IBM.XMS.IMessageConsumer
            oProcessor = oSession.CreateConsumer(oTopic)

            Dim oCurrMessage As IBM.XMS.IMessage
            oCurrMessage = oProcessor.ReceiveNoWait

            While Not oCurrMessage Is Nothing
                With CType(oCurrMessage, IBM.XMS.ITextMessage)
                    .JMSType = IBM.XMS.MQC.MQMT_REPLY
                    .ClearBody()
                    .Text = "Yo! Back at you!"
                End With

                Dim oReplier As IBM.XMS.IMessageProducer = oSession.CreateProducer(oCurrMessage.JMSReplyTo)
                oCurrMessage.JMSDestination = oCurrMessage.JMSReplyTo
                oReplier.DeliveryMode = IBM.XMS.DeliveryMode.NonPersistent
                Try
                    oReplier.Send(oCurrMessage)
                Catch ex As Exception
                    Throw ex
                Finally
                    CloseAndDispose(oReplier)
                End Try

                oCurrMessage = oProcessor.ReceiveNoWait
            End While

            CloseAndDispose(oProcessor)
            oProcessor = Nothing

            CloseAndDispose(oSession)
            oSession = Nothing

        Catch ex As Exception
            Dispose(oTopic)
            oTopic = Nothing
            CloseAndDispose(oConnection)
            oConnection = Nothing
            oConnectionFactory = Nothing
            oFactory = Nothing
        End Try

    End Sub
[/code]
Back to top
View user's profile Send private message
Vitor
PostPosted: Fri Aug 21, 2009 12:05 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 11 Nov 2005
Posts: 26093
Location: Texas, USA

Thank you for posting the solution for the benefit of others!

In defence, I never said receive was wrong, just unusual. If it works and performs to your satisfaction then go in peace.
_________________
Honesty is the best policy.
Insanity is the best defence.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Goto page 1, 2  Next Page 1 of 2

MQSeries.net Forum Index » IBM MQ API Support » iMessageConsumer - how does one reply to the message
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.