为SilverLight实现WCF可靠服务的自己设计的问题(basicHttpBinding)

时间:2009-07-05 04:20:21

标签: wcf silverlight soap behavior

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

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

如果ID是== lastID,我假设客户端从未收到我的消息,我想简单地返回缓存响应对象而不是重新处理请求。我编写了一个MessageInspector Behavior对象,我将其注入到WCF Endpoint行为中。该对象实现了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的值为“correlationState”。不,正如我最初预期的那样,请求的新返回值。问题是,我可以阻止消息处理到此位置的服务并返回“缓存”响应吗?

实际上这个问题的更好版本是:这是处理缓存和响应跟踪的适当“注入”位置吗?如果没有,那么“已批准的ms”或更好的方式可以实现此请求跟踪和恢复?

感谢。

-Jeff

2 个答案:

答案 0 :(得分:0)

我认为你在这里试图重新发明轮子。 WCF的Reliable Messaging旨在确保邮件传递。我试试,除非你不想出于特定原因使用它吗?

答案 1 :(得分:0)

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

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

如果有人想要这个解决方案的完整工作代码,请在此处删除注释,并在完成最终调试和单元测试后发布最终代码。

-Jeff