0

SilverlightからWCFサーバーへの通信の信頼性を向上させるために、非常に基本的な信頼性の高いメッセージ状態処理システムを実装しようとしています。

私は、メッセージIDとして増分整数を含むカスタムメッセージヘッダーをSOAPリクエストに導入するルートを取りました。WCFサーバーでリクエストを受信したときに、メッセージIDを確認したいという考え方です。IDが>最後のIDである場合は、単にリクエストを実行し、リクエストの後に、結果のコピーを新しいIDと一緒にキャッシュします。

IDが==lastIDの場合、クライアントがメッセージを受信したことがないと想定し、リクエストを再処理するのではなく、キャッシュされた応答オブジェクトを返すだけです。WCFエンドポイントの動作に挿入するMessageInspectorBehaviorオブジェクトを作成しました。このオブジェクトは、次の2つのメソッドを持つIDispatchMessageInspectorを実装します。

object IDispatchMessageInspector.AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel, InstanceContext instanceContext)
{
    // Get the incoming message headers and get the messageId
    var idx = request.Headers.FindHeader("ClientRequestId", "");
    if (idx >= 0)
    {
        var requestHeader = request.Headers[idx];
        int requestId = 0;
        if (Int32.TryParse(requestHeader.ToString(), out requestId))
        {
            int lastRequest = myCache.GetLastId();
            if (requestId <= lastRequest)
            {
                // @TODO - Send back the saved message
                var reply = myCache.GetLastResponse();
                if (reply != null)
                {
                    /// ERK -- > Woops, how do I override the service
                    /// and make the reply here?
                }
            }
            myCache.SetLastId(requestId);
        }
    }
    return null;
}

void IDispatchMessageInspector.BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
    var requestId = myCache.GetLastId();
    if (requestId > 0)
    {
        myCache.SetLastResponse(reply);
    }
}

さて、私が遭遇した問題は明らかなはずです... AfterReceiveRequestの戻り値(オブジェクト)は、BeforeSendReplyに「correlatedState」として渡される値です。当初の予想どおり、リクエストの新しい戻り値ではありません。問題は、この場所のサービスへのメッセージの処理を停止して、「キャッシュされた」応答を返すことができるかどうかです。

実際、この質問のより良いバージョン:これはキャッシングと応答追跡を処理するための適切な「注入」場所ですか?そうでない場合、この要求の追跡と回復を達成するための「承認されたミリ秒」またはより良い方法はどこにありますか?

ありがとう。

-ジェフ

4

2 に答える 2

0

ここで少し車輪の再発明をしようとしていると思います。WCFには、メッセージ配信を確実にするように設計された信頼性の高いメッセージングがあります。特別な理由で使いたくないのでなければ、やってみますか?

于 2009-07-06T15:34:17.257 に答える
0

多くの試練と苦難の末、私は自分の問題の解決策を見つけました。それは、エレガントではないにしても、機能的です。

重複するサービスリクエストを検出したときにサービスエンドポイントへの呼び出しをバイパスするために、FaultExceptionをスローするだけです。次に、BeforeSendReplyメソッドで、 replay.IsFaultかどうかを確認し、その障害がAfterReceiveRequestでスローした特定の障害コードであるかどうかを確認します。もしそうなら、私はメッセージ応答のキャッシュされたコピーを返します。FaultExceptionメカニズムは、サービス呼び出しをバイパスするために使用する必要があるものです。

このソリューションで完全に機能するコードが必要な場合は、ここにメモをドロップしてください。最終的なデバッグと単体テストが完了したら、最終的なコードを投稿します。

-ジェフ

于 2009-07-07T02:06:21.517 に答える