1

キュー内の最新のメッセージ(msmq)からのデータを公開することになっているアクションを持つコントローラーを持つMVCアプリがあります。ローカルマシンにプライベートキューを追加しました。メッセージが追加されたときに、アプリケーションがキューからメッセージを自動的に受信するようにしたい。このために、アプリケーションに追加されたWCFサービスでmsmqIntegrationBindingを使用しています。コントラクトでメッセージを受け取るメソッドは、クライアントが最新のデータを要求したときにアクセスできるように、メッセージをアプリケーションキャッシュに保存することになっています。

私が今直面している課題は、キューにメッセージを追加したときに、WCFサービスによってメッセージが取得されないことです。間違っている可能性のあることについてのガイダンスや、アプローチに関するフィードバックが必要です。助けてください。

以下は、WCFサービスのendpoint-configです。

<bindings>
<msmqIntegrationBinding>
  <binding name="MsmqBinding">
    <security mode="None" />
  </binding>
</msmqIntegrationBinding>
</bindings>

<services>
  <service name="TestApp.Web.Service.QueueMessageReceiver">
    <endpoint address="msmq.formatname:DIRECT=OS:.\private$\testsmessagequeue"
                      binding="msmqIntegrationBinding"
                      bindingConfiguration="MsmqBinding"
                      contract="TestApp.Web.Service.IQueueMessageReceiver" />
  </service>
</services>

そして、次のコードはQueueMessageReceiver.csWCFサービスからのものです。

public class QueueMessageReceiver : IQueueMessageReceiver
{
    private static readonly XmlSerializer Serializer = new XmlSerializer(typeof(ScrewInfoModel));

    [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
    public void PutScrewInfoMessage(System.ServiceModel.MsmqIntegration.MsmqMessage<System.Xml.XmlDocument> msg)
    {
        CacheScrewInfoModelFromScrewInfoXmlDoc(msg.Body);
    }

    private static void CacheScrewInfoModelFromScrewInfoXmlDoc(XmlNode screwInfoXmlDoc)
    {
        var reader = new StringReader(screwInfoXmlDoc.InnerXml);
        var screwInfoModel = (ScrewInfoModel)Serializer.Deserialize(reader);
        Common.Utils.CacheScrewInfo(screwInfoModel);
    }
}

そして、これがWCFのインターフェースです。

[ServiceContract]
public interface IQueueMessageReceiver
{
    [OperationContract(IsOneWay = true, Action = "*")]
    void PutScrewInfoMessage(MsmqMessage<XmlDocument> msg);
}
4

1 に答える 1

0

運用契約をに変更してみてください

void PutScrewInfoMessage(MsmqMessage<string> msg);

WCFスタックがへの逆シリアル化に問題がある可能性がありますXmlDocument

アップデート

試すべきこと:

  1. キュー「testsmessagequeue」に正しい権限が設定されていることを確認してください。この場合、コントローラーをホストしているアプリプールを実行しているサービスアカウントには、「メッセージの受信」権限が設定されている必要があります。

  2. イベントビューアの[アプリケーションとサービスログ]->[Microsoft]->[Windows]-> [MSMQ]-> [End2End]にあるMSMQログを有効にします(Windows2008サーバーまたはWindows7以降を使用している場合)。これにより、エラーを含め、MSMQで発生するすべてのものがキャプチャされます。

  3. キューをトランザクション化してみてください(まだ行っていない場合)。これにより、メッセージの配信不能時にエラー状態が確実に存在します。

  4. サービスエンドポイントでWCFトレースを有効にして、メッセージのデキュー時に発生する特定のWCFエラーを確認します。

更新2

問題はキューのアクセス許可だと思います。アプリプールは、ユーザーApplicationPoolIdentityで実行されています(.net 4.0アプリプールで実行されている場合)。このIDに対応するユーザーはDefaultAppPoolと呼ばれます。このユーザーにキューでのメッセージ受信許可を与える必要があります。このユーザーを選択するには、[ユーザーの選択]ダイアログでIIS AppPool\DefaultAppPoolというローカルアカウントを検索します。

ここに画像の説明を入力してください

更新3

IISがキューリスナーにとって適切なホスティングコンテナではないことに気づきました。これは、非アクティブな期間が経過するとアプリプールがアンロードされるためです。これはIISによって制御され、構成できません。(ここを参照)

キューエンドポイントをホストするには、Windowsサービスで新しいホスティングコンテナを作成する必要があると思います(コンソールホストを使用してこれをスパイクできます)。Windowsサービスは実際のサービスアカウントで実行されるため、アクセス許可の付与はそれほど複雑ではありません。

このサービスは、キャッシュに直接書き込みを書き込むことができます。これが不可能な場合は、Webサイトコントローラーがキャッシュを更新できるDBに書き込む必要があります。

これは意味がありますか?

更新4

ポイズンメッセージは、メッセージに何らかの問題があるため、メッセージをデキューできないことを意味します。Transactional Dead Letter Queueというシステムキューをチェックして、メッセージがそこにあるかどうかを確認します。

于 2012-07-24T09:05:18.750 に答える