0

我正在尝试实现一个非常基本的可靠消息状态处理系统,以提高 Silverlight 与 WCF 服务器通信的可靠性。

我采用了将自定义消息头引入到包含递增整数作为消息 ID 的 SOAP 请求的方法。这个想法是,当我在 WCF 服务器收到请求时,我想检查消息 ID。如果 ID 大于最后一个 ID,那么我只需执行请求并在请求之后,将结果的副本与新 ID 一起缓存。

如果 ID 是 == lastID,我假设客户端从未收到我的消息,我只想返回缓存的响应对象,而不是重新处理请求。我编写了一个 MessageInspector Behavior 对象,将其注入到 WCF 端点行为中。该对象实现了 IDispatchMessageInspector,它有 2 个方法:

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 返回值(对象)是作为“correlatedState”传递给 BeforeSendReply 的值。不像我最初预期的那样,请求的新返回值。问题是,我可以在这个位置停止消息处理到服务并返回“缓存”响应吗?

实际上这个问题的更好版本:这是处理缓存和响应跟踪的适当“注入”位置吗?如果没有,“批准的毫秒”或完成此请求跟踪和恢复的更好方法在哪里?

谢谢。

-杰夫

4

2 回答 2

0

经过多次试验和磨难,我找到了解决问题的方法,即使不优雅,也很实用。

为了在检测到重复的服务请求时绕过对服务端点的调用,我只需抛出一个FaultException。然后在BeforeSendReply方法中,我检查是否是replay.IsFault ,然后检查故障是否是我在AfterReceiveRequest中输入的特定故障代码。如果是这样,我返回消息响应的缓存副本。我需要使用 FaultException 机制来绕过服务调用

如果有人想要此解决方案的完整工作代码,请在此处留言,我将在完成最终调试和单元测试后发布我的最终代码。

-杰夫

于 2009-07-07T02:06:21.517 回答
0

我认为您正在尝试在这里稍微重新发明轮子。WCF 具有可靠的消息传递,旨在确保已经传递消息。我会尝试,除非那是您不想出于特定原因使用它?

于 2009-07-06T15:34:17.257 回答