8

サーバー THOR でトランザクション MSMQ キューをセットアップしています。次のコードを使用して、ワークステーションからそのキューにメッセージを投稿できます。

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

ただし、WCF を使用して接続しようとすると、メッセージがキューに表示されません。私が使用している構成は次のとおりです。

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

そしてコード:

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

いかなる種類の例外も発生しませんが、THOR のキューに投稿されたメッセージはありません。何か案は?黙って失敗するだけなので、これをデバッグする方法さえわかりません。

アップデート

MSMQ URI を「net.msmq://localhost/private/myqueue」に変更すると、セットアップしたローカル トランザクション キューに送信されます。キュー自体のセットアップは同じです (同じ手順を実行して、localhost キューと THOR キューの両方を作成しました)。

4

5 に答える 5

3

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:

于 2010-10-05T16:21:24.623 に答える
0

私も同様の問題を抱えていたので、このチェックリストが役立つことを願っています:

  1. コネクティビティ: DNS エントリが機能していると思います。それがpingを行うことを確認してください...
  2. 異なるドメインにまたがるアクセス許可: いくつかのスプリントの前にこれに問題がありました。その理由はアクセス許可でした。私のテスト用ローカル マシンは、サーバーとは異なるドメインにありました。トールとあなたのマシンが同じドメインにあることを確認してください。ドメイン間で実行することは可能ですが、動作させることができませんでした (そのため、テストを同じドメイン内のマシンに移動しました)
  3. キュー ツール: 管理ツールからキューを表示できますが、キュー エクスプローラー ツール ( http://cogin.com/mq/index.php ) が非常に便利であることがわかりました。メッセージがスタックしている場所を確認できます。

注:おそらく1で問題ありませんが、念のため入れておきます...

于 2010-10-06T12:22:08.053 に答える
0

チャネルを閉じる前に、transaaction スコープを完了してみてください。

チャネルを閉じると、チャネルとの接続が失われ、コミットされていないトランザクションが存在し、最終的に破棄されます。

于 2010-10-05T16:00:01.523 に答える
0

MsmqIntegrationBinding を使用する必要があります。メッセージは認識されておらず、WCF がメッセージの内容を認識していないため、破棄されています。

于 2010-10-11T16:20:32.913 に答える