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).
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:
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).
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:
The first option if of course safer but it requires MSMQ to be installed with Active Directory integration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With