views:

66

answers:

4

I have a transactional MSMQ queue setup on server THOR. I am able to post messages to that queue from a workstation with the following code:

var queue = new MessageQueue("FormatName:Direct=OS:thor\\private\\myqueue");
using (var tx = new MessageQueueTransaction())
{
   tx.Begin();
   queue.Send("test", tx);
   tx.Commit();
}

However, when I attempt to connect using WCF my messages never appear in the queue. Here is the configuration I'm using:

<system.serviceModel>
  <bindings>
    <netMsmqBinding>
      <binding name="ClientNewsFeedServiceBinding" durable="true" exactlyOnce="true">
        <security mode="None" />
      </binding>
    </netMsmqBinding>
  </bindings>

  <client>
    <!-- NewsFeed Service -->
    <endpoint name="INewsFeedService"
              address="net.msmq://thor/private/myqueue"
              binding="netMsmqBinding"
              bindingConfiguration="ClientNewsFeedServiceBinding"
              contract="Service.Contract.INewsFeedService" />
  </client>
</system.serviceModel>

And the code:

using (var tx = new TransactionScope())
{
   var cf = new ChannelFactory<INewsFeedService>("INewsFeedService");
   var service = cf.CreateChannel();
   service.TestMessage("test");
   ((IChannel)service).Close();
   tx.Complete();
}

I get no exceptions of any kind, but there is no message posted on the queue on THOR. Any ideas? I don't even know how to debug this since it just silently fails.

UPDATE

If I change my MSMQ URI to 'net.msmq://localhost/private/myqueue' then it will post to a local transactional queue I have setup. The setup of the queue itself is identical (as in, I performed the same steps to create both the localhost and THOR queues).

A: 

Try completing the transaaction scope before you close the channel.

When you close the channel you loose contact with it, it therefore has an uncommitted transaction, which is eventually discarded.

Shiraz Bhaiji
That didn't work. What you say makes sense, but didn't seem to make a difference.
AgileJon
A: 

I believe if you make your queue transactional on the MSMQ server side, you need to specify a few more settings in your WCF binding config - try this:

<bindings>
    <netMsmqBinding>
      <binding name="ClientNewsFeedServiceBinding" 
               durable="true" exactlyOnce="true">
        <security mode="None" />
      </binding>
    </netMsmqBinding>
  </bindings>

If I'm not mistaken, you need to add the durable="true" and exactlyOnce="true" attributes to your netMsmq binding for this to work.

There's a really good tutorial on how to get MSMQ and WCF to work nicely together:

Tom covers transactional queues in part 3, and mentions:

The exactlyOnce="true" attribute is WCF-speak for using a transactional message queue.

The durable=true only means to have the messages flushed to disk right away, instead of keeping them in server memory. It's slower, but in case of a server crash or power interrupt, messages aren't lost. Classic speed vs. reliability tradeoff....

Update: since you're going "across" machine boundaries, and you're using transactional queue - have you checked the DTC (Distributed Transaction Coordinator) on all machines involved?? Check out Tom's blog part 3:

Check DTC Configuration

Our epic journey is almost at an end. In fact if you're still playing along at home, you can try running the application with the transactional queues to see if it's working. If it's failing, one possible cause is problems with your Distributed Transaction Coordinator configuration. Here are a few things to try:

marc_s
Tried that, no go. I added an update to my original post to say that I AM able to run the WCF code if I update my MSMQ URI to point to localhost instead of THOR.
AgileJon
A: 

I had similar problem, so I hope this checklist helps:

  1. Connectivity: I suppose that thor DNS entry is working, isn't it? Check that it makes ping...
  2. Permissions across different domains: I had problems some sprints ago with this, the reason was permissions. My testing local machine was in a different domain than the server. Check that thor and your machine are in the same domain. Is possible to have it accross domains, but I could not have it working (so I moved my tests to a machine in the same domain)
  3. Queue tool: Although you can see queues from Administrative tools I found Queue explorer tool (http://cogin.com/mq/index.php) pretty useful. You can check where are the messages getting stuck.

NOTE: probably 1 is ok, but just in the case I put it...

cad
A: 

You need to use the MsmqIntegrationBinding. The messages are not being recognized and are getting discarded since WCF doesn't know what they are.

Adam Fyles
I thought MsmqIntegrationBinding was for intercommunication between WCF apps and non-WCF apps. The example code where I manually added something to the queue was just to show that it wasn't a simple "turn off your firewall" issue. In production the queue will only be accessed by WCF services.
AgileJon
My apologies, my eyes skipped by the 2nd client. Is the client an XP machine? We've had Kerberos trouble with XP. There is a patch for it.
Adam Fyles