25

Okay, here is a very simple and fundamental question. If I have an application on windows machine A that wants to write to a queue on windows machine B, do I need to have MSMQ installed on machine A (even though there is no queue there)? I am just beginning to use queues for my applications and trying to figure some fundamentals out.

Thanks

Dan Appleyard
  • 7,195
  • 13
  • 47
  • 79

4 Answers4

47

Yes, you need MSMQ installed locally to write to a remote queue. If you're writing to a private queue, take a look at this page which has useful information on how to format the queue name. If you're writing to a remote Transactional queue, then you need to make sure you specify that correctly (point 5)

This is the article text:

1. When working with remote queues, the queue name in the format machinename\private$\queuename doesn't work. This results in an "invalid queue path" error.

2. The queue name has to be mentioned as FormatName:Direct=OS:machinename\\private$\\queuename.

This is necessary since the queue access is internally done using the format name syntax only. The other friendly representation is converted to the FormatName and then used. When working with remote queues, unless there is an AD to resolve the queue name, the friendly name won't work. Check out documentation for details.

For Eg.

MessageQueue rmQ = new MessageQueue 
              ("FormatName:Direct=OS:machinename\\private$\\queue");
rmQ.Send("sent to regular queue - Atul");

3. Further to previous point, note that FormatName is case sensitive. If you mention the earlier string as FORMATNAME:Direct=OS:machinename\\private$\\queuename, it won't work. Surprisingly, there is no error thrown in this case. "FormatName" part of the string seems to be the only case sensitive part. Others can appear in different case. For eg. You can write "DIRECT".

4. In case you want to use the machine's IP address the syntax will be FormatName:Direct=TCP:ipaddress\\private$\\queuename.

For Eg.

MessageQueue rmQ = new MessageQueue
              ("FormatName:Direct=TCP:121.0.0.1\\private$\\queue");
rmQ.Send("sent to regular queue - Atul");

5. The transactional properties of the queue instance you create in code should match with that of the queue you are trying to send the message to. So in the earlier examples, I was sending message to a non-transactional queue. To send to a transactional queue, the code would be

MessageQueue rmTxnQ = new MessageQueue
            ("FormatName:Direct=OS:machinename\\private$\\queue");
rmTxnQ.Send("sent to Txn queue - Atul", MessageQueueTransactionType.Single);

If the transactional properties don't match, the message will not be delivered. The surprising part is again, I didn't get any error, and the message just disappeared

6. Finally, when you send messages to remote queue, a temporary outgoing queue is created on your own machine. This is used in case the remote queue is unavailable. If you go to the computer Management console (compmgmt.msc), and expand the Services and Applications / Message Queuing / Outgoing Queues, you would see these queues. The right side of the console should show the details including the state (connected or not) and the IP address(es) for the next hop(s).

stuartd
  • 62,136
  • 13
  • 120
  • 150
  • yeah, that is what i thought. I just wanted to hear it from someone else. I am using private queues (already have the format part done). ONE POINT FOR GRYFFINDOR! – Dan Appleyard Jun 10 '11 at 16:24
  • After made changes as per above settings (rights & MSMQ installation) : queue.send() : working fine. But either queue.receive() or queue.getMessageEnumerator2() not working. Can you help me out?? I am testing this in my local machine (Installed MSMQ components). – watraplion Sep 27 '17 at 15:35
  • 1
    @watraplion you should ask a new question. – stuartd Sep 27 '17 at 17:44
  • As an aside be aware that for a remote queue, an actual machine name must be provided. A DNS alias does not work. – paulroho Apr 04 '19 at 11:51
8

All MSMQ communication requires an MSMQ queue manager at each end. MSMQ-using applications communicate with their local queue manager which does the work for them. MSMQ-using applications cannot communicate directly with any queues, local or remote.

John Breakwell
  • 4,622
  • 17
  • 25
3

Another (instead of installing MSMQ on the local machine running the client) would be to implement a WCF service which takes its messages from an MSMQ queue. In that case, your remote client would only have to specify the remote service endpoint for it to write directly to the remote queue. You would also have to be careful that the security on the remote queue was set correctly.

I think this would be a better way of implementing queue-based communication. This is a short answer, but I will happily expand if you're interested (I noticed that you were pretty happy with the other answer :)

Rendition
  • 494
  • 2
  • 12
  • No, I just wanted clarification. Your proposed WCF service isn't using MSMQ integration, is it? It just happens to consume MSMQ messages. – John Breakwell Jun 14 '11 at 20:39
  • Hi, The WCF service runs on the remote server and consumes messages coming in. The client - via proxy - uses the service contract (via http and net.msmq) and writes into the queue where ther service can pick it up. Another way would be to use a vanilla service which writes to the queue and just using http. Then you wouldn't require msmq on the client machine. – Rendition Jun 16 '11 at 13:45
0

below format worked for us

key="PublicQueueName" value="FormatName:Direct=TCP:192.168.12.58\private$\myqueue"

Also you would require to give remote queue access permissions

security: Allow Anonymus login

enter image description here

abksharma
  • 515
  • 6
  • 23