Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are my queued WCF messages silently disappearing?

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).

like image 233
AgileJon Avatar asked Oct 05 '10 15:10

AgileJon


2 Answers

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:

  • MSMQ, WCF and IIS: getting them to play nicely (part 1 of 3)
  • MSMQ, WCF and IIS: getting them to play nicely (part 2 of 3)
  • MSMQ, WCF and IIS: getting them to play nicely (part 3 of 3)

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:

like image 120
marc_s Avatar answered Oct 17 '22 17:10

marc_s


I had the same problem. After trying out all the ideas listed here I started looking for something else. It turned out that when you select the security mode None the sender properties of me message are left empty (see picture below).

MSMQ Message properties

Such message will be accepted when it is sent to a localhost but it will be rejected by the remote server.

In order to make it working you have few options:

  1. Enable authentication
  2. Grant Send permissions to the ANONYMOUS LOGON

The first option if of course safer but it requires MSMQ to be installed with Active Directory integration.

like image 45
StanislawSwierc Avatar answered Oct 17 '22 19:10

StanislawSwierc