Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为SilverLight(basicHttpBinding)实现自己的WCF可靠服务设计时出现问题_Wcf_Silverlight_Soap_Behavior - Fatal编程技术网

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

为SilverLight(basicHttpBinding)实现自己的WCF可靠服务设计时出现问题,wcf,silverlight,soap,behavior,Wcf,Silverlight,Soap,Behavior,我正在尝试实现一个非常基本的可靠消息状态处理系统,以提高Silverlight到WCF服务器通信的可靠性 我采取了在SOAP请求中引入自定义消息头的方法,该消息头包含一个递增整数作为消息ID。其思想是,当我在WCF服务器上收到请求时,我要检查消息ID。如果ID>最后一个ID,那么我只需执行请求,然后在请求之后,我将结果的副本与新ID一起缓存 如果ID=lastID,我假设客户端从未收到我的消息,我只想返回缓存的响应对象,而不是重新处理请求。我已经编写了一个MessageInspector行为对象

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

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

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

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

谢谢


-杰夫

我想你是想在这里稍微改造一下轮子。WCF有一个专门为确保消息传递而设计的框架。我会试试看,除非你出于某种特定的原因不想使用它?

经过多次尝试和磨难,我找到了一个解决我问题的方法,如果不是优雅的,也是实用的

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

如果有人想要这个解决方案的完整工作代码,请在这里写一条注释,我将在完成最终调试和单元测试后发布我的最终代码


-Jeff

是的,但据我所知,silverlight中不提供WCF可靠消息。Silverlight只实现basicHttpBinding,据我所知,它不支持可靠的消息传递。