Infosys Microsoft Alliance and Solutions blog

« Software Factory: Domain-Specific Modeling | Main | Hello World! »

MSMQ - Receiving messages from remote private queues

Sometime back I had blogged about how to send messages to remote private queues. There were a few queries on how to read from remote queue as well.

To me it should have worked by using the MessageQueue.Receive API instead of .Send. I decided to give this a try anyway and it indeed is as trivial as that. However a few things to take care while trying to get this working.

1. Check the documentation to see where all the API works. The API may have limitations in working in workgroup mode if you are not using the direct format name syntax.

2. The other very important aspect is setting the formatter prior to receiving the message. You need to set this appropriately to binary or XML and specific type to ensure successful read.

To show a complete example, find below code that posts to the remote queue (transactional as well as non-transactional) and also reads from them. To keep things simple, I have used a simple string message here. However you can definitely use more complex types and custom types for sending and receiving (as long as they match both ways).

        private void btnPostToQueue_Click(object sender, EventArgs e)

        {

            //post to regular non-transactional remote queue using OS name

            MessageQueue rmQ = new MessageQueue("FormatName:Direct=OS:punhjw30076\\private$\\remote");

            rmQ.Send("sent to regular queue - Atul");

 

            //post to  transactional remote queue using IP address

            MessageQueue rmTxnQ = new MessageQueue("FormatName:Direct=TCP:100.100.100.12\\private$\\remoteTxn");

            rmTxnQ.Send("sent to transacted queue - Atul", MessageQueueTransactionType.Single);

        }

 

        private void btnGetFromQueue_Click(object sender, EventArgs e)

        {

            //retrieve from regular non-transactional remote queue using OS name

            MessageQueue rmQ = new MessageQueue("FormatName:Direct=OS:punhjw30076\\private$\\remote");

            rmQ.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });

            System.Messaging.Message msg = rmQ.Receive();

            MessageBox.Show(msg.Body.ToString());

 

            //retrieve from transactional remote queue using IP address

            MessageQueue rmTxnQ = new MessageQueue("FormatName:Direct=TCP:100.100.100.12\\private$\\remoteTxn");

            rmTxnQ.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });

            System.Messaging.Message msgTxn = rmTxnQ.Receive(MessageQueueTransactionType.Single);

            MessageBox.Show(msgTxn.Body.ToString());

        }

Hope this helps !

TrackBack

TrackBack URL for this entry:
http://www.infosysblogs.com/microsoft-mt/mt-tb.fcgi/100

Comments

Atul, Much appreciated article, recently, very recently I've been trying to do this... ended up with error. good work.

Mahesh: Glad you found it useful

Could not read from remote queue. Because it was not able to find remote computer using direct format over http or os. I am able to send message to same remote queue using direct format name http.

@Kobita, ideally the same convention should work for both send and receive. I hope you had checked the basic things like the server is up and running and using transactions if it is a transactional queue.

Another important aspect when receiving message is the right formatter to be used to read the message.

Atul, this article was very useful. Good work - simple and precise!

@Raj, thanks.

Hi: I'm using the same code to receive a message from MSMQ Server in other domain and got an error "MessageQueueErrorCode -2147023071 System.Messaging.MessageQueueErrorCode" can anybody help me ?

@Juan, did you capture the error correctly? Check here for the details around MessageQueueErrorCode enumeration - http://msdn2.microsoft.com/en-us/library/system.messaging.messagequeueerrorcode.aspx

The values of the enumeration can be found here - http://www.koders.com/csharp/fidE632059BF610D9D912C019A96DCF7A2DD76C847F.aspx

I used the exact command listed in the previous posts, but in vain.

Basically, I want to send a message to a remote private queue. On debug, no error occured and the message seems to have been successful.

However, I can still see it in the outgoing queue on the local machine as if it was being blocked somehow.

Here is the command I use : MessageQueue Queue = new System.Messaging.MessageQueue("FormatName:Direct=OS:wmqdev\\private$\\filesar").

That should work, should it not?

Moreover, the status "Department" is "connected" and the IP address also matches.

I also used this command with the IP address of the remote machine (FormatName:Direct=TCP:.......\\private$\\filesar) but it didn't solve the problem either.

I have been looking for the solution for days. Nevertheless, can't get my head around it.

If someone could help me out!

P.S.:I am using the C# programming language .NET framework 1.1

Thank you very much.

Youss, not sure what is "Department". From the code it looks like your remote machine name is "wmqdev". Can you ensure that this remote machine is up and running and that MSMQ Service is also running on that machine.

Also do verify that Everyone has write access to the queue (filesar) or atleast the write access is provided to the ID from which you are trying to write to the queue.

Displayed an error as Remote server is not available.

I followed steps to receive msg from remote MSmq but am getting the following error :
The specified format name does not support the requested operation. For example, a direct queue format name cannot be deleted.

hi ,
please can somebody help me in this regard .
we have transactional private queue which has no of msgs situated on machine A , i just want to receive messages from machine A 's private transactional queue to machine B using windows service . i am continiously getting following error
"The specified format name does not support the requested operation. For example, a direct queue format name cannot be deleted."
Atul help on this issue will be appriciated .
please let me know !!!!!!!!!

Rashmi, can you post the code here about how you are trying to receving the message from the remote queue? The error you have mentioned means an incorrect naming of the remote queue. Else, feel free to send me the code at atulg AT infosys DOT com

code is as follows
oQueuePath = new StringBuilder(@"FormatName:Direct=OS:chintan\Private$\interfacelogqueue");
m_oListener = new MSMQListener(oQueuePath.ToString());
m_oListener.FormatterTypes = new Type[] { typeof(String) };
m_oQueue.Formatter = new XmlMessageFormatter(m_arrTypes);
m_oQueue.Formatter = new XmlMessageFormatter(m_arrTypes);
m_oQueue.PeekCompleted += new PeekCompletedEventHandler(OnPeekCompleted);

m_oQueue.ReceiveCompleted += new ReceiveCompletedEventHandler(OnReceiveCompleted);

now ,
method onpeekcompleted

oTran = new MessageQueueTransaction();

oTran.Begin();
oMessage = m_oQueue.Receive(MessageQueueTransactionType.Single);
oTran.Commit();

hi atul,
the exact lines where i am getting problem is
if (m_oQueue.Transactional) {
m_oQueue.BeginPeek();
}
else {
m_oQueue.BeginReceive();
}
if condition itself .......as it cant support direct format ,
any suggestions ?

Rashmi, you are getting the error since you are calling the Transactional property which is not available for remote queues. See here for details - http://msdn2.microsoft.com/en-us/library/system.messaging.messagequeue.transactional.aspx

In your case, since you know which queue you are polling, you will also know if it is transactional or not and you need to directly use that knowledge in the code.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)