C# dotnet MSMQ Remote Private Queues
I am working on a project and needed to communicate between two XP pro machines that are not in a domain. Initially I wrote a named pipe wrapper because its quick and dirty. However, my server was getting bogged down and dropping messages. I decided to switch to MSMQ since it will give me some message reliability.This was very easy to do on my local computer.
MessageQueue mq = null;
if (!MessageQueue.Exists(@”mymachine\private$\myqueue”))
mq = MessageQueue.Create(@”mymachine\private$\myqueue”);
Seemed easy enough, however, when I deployed the project to a remote machine I was greeted with “The remote computer is not available” exception. I did a lot of googling and came across some Active Directory posts etc… it cant resolve the name or DNS problems. I did a ping from the client and it could see the server so DNS resolution was not the problem. After spending a great amount of time playing with this, I found a post that said you need to set the format name property of the queue for a private queue implementation.
However, in dotnet queues the format name property is read only. Not to worry though, the constructor of the queue can take a format name. So I changed my code to something like this:
string queueName = @”FormatName:Direct=OS:mymachine\private$\myqueue”;
MessageQueue mq = null;
if (!MessageQueue.Exists(queueName))
mq = new MessageQueue(queueName);
return mq;
This should work right?? Nope, I started getting a “Cannot determine whether a queue with the specified format name exists.” exception. So I consulted MSDN to see what the heck this means. I know it exists, I checked it on the server. About half way down the MSDN page you will see this little comment “No method exists to determine whether a queue with a specified format name exists” and we are using format names. What?? There is no way to check if it exists? It seems the exists method actually calls out to Active Directory to see if the queue is valid.
What to do now? Just call the CanWrite property instead. So now the code looks something like this:
string queueName = @”FormatName:Direct=OS:mymachine\private$\myqueue”;
MessageQueue mq = new MessageQueue(queueName);
if (!mq.CanWrite)
throw new ApplicationException(”Cannot write to the server queue”);
return mq;
The bad news:
It seems that CanWrite always returns true for remote queues, I stopped my server and the exception was never thrown. This is not the case if the queue is on the same machine.
The good news:
If both queues are running the messages get through. I am working on figuring out how to determine if the remote queue is available.
September 16th, 2006 at 1:38 pm
Hi, could you make use of MQMgmtGetInfo (from the local administration API) which takes machine name and queue name? Cheers, John.
September 18th, 2006 at 7:37 am
Hey John, this looks like a possibility. If I get some time I will check into getting that to work in c# with a pinvoke. There is a good solution out there if you want to write a managed wrapper on Jareds Technical blog.
http://jarednevans.typepad.com/technoblog/net_framework_or_aspnet/
November 30th, 2007 at 11:30 pm
Hi,
Did you ever figure this out, I’ve have the same problem.
Thanks,
Gary
December 2nd, 2007 at 6:10 pm
Thanks for the clarification. Apparently (at least in 2.0) it’s still buggy. You can send messages to a remote MSMQ, but not read from one. It’s very disappointing.