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」として渡される値です。当初の予想どおり、リクエストの新しい戻り値ではありません。問題は、この場所のサービスへのメッセージの処理を停止して、「キャッシュされた」応答を返すことができるかどうかです。
実際、この質問のより良いバージョン:これはキャッシングと応答追跡を処理するための適切な「注入」場所ですか?そうでない場合、この要求の追跡と回復を達成するための「承認されたミリ秒」またはより良い方法はどこにありますか?
ありがとう。
-ジェフ