WCF Silverlight客户端获取404未找到轮询消息的响应

最终WCF双工Silverlight 4客户端在WCF服务发送给Silverlight客户端后立即获得404 Not Found轮询消息的错误,有时候这种情况会发生在第二轮投票中,有时连接工作几小时甚至几天,但大多数情况下会在第一分钟内失败。

! 有趣的是,这个问题就像使用MaxMessagesPerPoll双工模式时已知的Silverlight 4 bug一样,并且在这里和这里描述了解决方案,但是我使用的是SingleMessagePerPoll模式。 ANYWAY我建议使用ClientStack ,但没有任何改变。

一般流程:

  • SL客户端执行WCF服务方法,收到响应
  • 然后立即SL客户端开始发送轮询消息到服务,然后获得第二或Ns轮询消息的例外

    System.Net.WebException:远程服务器返回一个错误:NotFound

  • Fiddler只显示轮询消息的空404响应
  • 然后引发客户端通道故障事件
  • 我试图在发生这种故障后重新连接SL客户端,单个重新连接重试流程:

  • 处理Faulted事件
  • 取消订阅所有频道事件,如Closed/Closing/Opened/Opening
  • 使用try { close } catch { abort }以正确的方式关闭频道
  • 所有下面在一个新的线程轮询线程:(我foudn这个工程稍微稳定 - 看到这篇文章)
  • 等待45-70秒
  • 使用相同的DuplexChannelFactory<T>实例创建一个新频道,订阅所有频道事件仅用于记录目的
  • 执行WCF服务方法
  • 1-10次重试(〜1-10分钟)后,客户端最终连接到服务器并继续正常轮询。

    在WCF服务日志中,我看到它得到所有的cleint请求,没有任何异常处理,所以Silverlight客户端似乎发生了一些事情。

    基本信息:

  • .NET Framework 4.0
  • PollingDuplex
  • 异步WCF方法
  • IIS 6.0托管WCF服务
  • Silverligth 4客户端
  • 客户端操作系统:Windows XP SP2
  • 服务器操作系统:Windows 2003 R2 SP2
  • NTLM身份验证
  • DuplexMode:SingleMessagePerPoll
  • 还有一个其他WCF服务在我的服务开始工作之前请求/应答,它不使用双工连接
  • 在SL客户端服务中,我将所有事件记录到UI中,以便查看所有事件流,并为每个特定事件准备好时间
  • IIS日志中没有错误,服务器事件日志
  • 客户:

    var binaryBinding = new BinaryMessageEncodingBindingElement();
    binaryBinding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
    
    var httpbindingElement = new HttpTransportBindingElement
    {
        MaxReceivedMessageSize = 131072
    };
    
    var pollingDuplexBindingElement = new PollingDuplexBindingElement
    {
        ClientPollTimeout = new TimeSpan(0, 0, 1, 30),
        InactivityTimeout = new TimeSpan(0, 8, 0, 0),
    };
    
    
    _binding = new CustomBinding(
               pollingDuplexBindingElement,
               binaryBinding,
               httpbindingElement)
           {
               SendTimeout = new TimeSpan(0, 0, 0, 45),
               CloseTimeout = new TimeSpan(0, 0, 0, 25),
               ReceiveTimeout = new TimeSpan(0, 8, 0, 0),
               OpenTimeout = new TimeSpan(0, 0, 0, 45)
           };
    
    
    httpbindingElement.AuthenticationScheme = AuthenticationSchemes.Negotiate;
    var endpoint = new EndpointAddress(_endpointAddress);
    _channelFactory = new DuplexChannelFactory<TWebService>(
                           new InstanceContext(instanceOfClientServiceClass), 
                           _binding, 
                           endpoint);
    
    
    // then this factory used to create a new channels
    // Also for a new channel I'm setting OpTimeout
    var contextChannel = newChannel as IContextChannel;
    if (contextChannel != null)
    {
       contextChannel.OperationTimeout = TimeSpan.FromSeconds(45);
    }
    

    服务器:

  • WCF,PerSession,多线程
  • 一切都是线程安全的
  • 执行时没有服务器服务异常
  • 很多日志记录让我看到服务上发生了什么
  • 所有WCF跟踪都使用switchValue All启用,没有任何可疑内容
  • <binding name="customName"
                 sendTimeout="00:01:00"
                 receiveTimeout="08:00:00"
                 openTimeout="00:01:00"
                 closeTimeout="00:00:35">
         <pollingDuplex
             inactivityTimeout="08:00:00"
             serverPollTimeout="00:01:00" />
             <binaryMessageEncoding />
               <httpTransport authenticationScheme="Ntlm"
                              maxReceivedMessageSize="131072">              
             </httpTransport>
    </binding>
    
    <behavior name="customBehavior">
            <dataContractSerializer maxItemsInObjectGraph="2147483647" />
            <serviceDebug includeExceptionDetailInFaults="true" />
            <serviceThrottling
                 maxConcurrentCalls = "500"
                 maxConcurrentSessions = "500"
                 maxConcurrentInstances = "500" />
    </behavior>
    

    如果一切似乎工作正常,那么也许这是一个网络基础设施/配置问题(例如dns配置)。 在本地运行或使用IP地址而不是主机名时是否遇到同样的问题?

    如果您在IIS中的站点上配置了多个绑定,也可能会出现类似问题(详情请参阅此处:http://blogs.msdn.com/b/rampo/archive/2008/02/11/how-can-wcf-support -multiple-IIS结合指定的每site.aspx)

    另一件事是你如何从服务器传达给客户。 如果你在循环中迭代客户端并逐个调用回调方法,那么你可能会得到超时,它会显示为404s。 回调通常应该在后台线程上调用(每个客户端一个)。

    根据你如何进行通信,这可能也是由死锁(当UI线程涉及发送/接收消息/回调服务时)引起的。


    当调查这个StackOverflow后描述的问题静态构造函数调用PerSession WCF服务两次我发现Polling Duplex开始工作稳定,当我切换底层AppPool IIS配置使用单个工作进程而不是2以前指定。 我不确定为什么2设置之前,因为我没有这台服务器,但无论如何,这是我现在拥有的 - 在同一台机器上启动的多个Silverlight客户端运行稳定,轮询民意测验投票和没有404错误,所有客户端重新连接IIS重新启动并重新启动后尝试1 ...

    请参阅性能应用程序池设置了解更多详细信

    TL; DR:当IIS托管WCF驻留在具有多个工作进程的AppPool中时 - 轮询双工变得不稳定。 因此,在高负载的情况下,IIS启动了第二个进程,并开始在第二个进程中创建WCF服务实例,所以当遇到客户端会话在一个进程中创建时的情况,但似乎轮询有时到达另一个进程,因为它并不知道当前连接/会话,所以开始拒绝这些消息和整个连接错误。

    因此,Polling Duplex by design不能在单个IIS服务器和AppPool的多个进程中进行扩展,换句话说,如果您有多个工作进程 - 这是WebGarden环境,并且双工不可跨网络农场和花园进行扩展

    链接地址: http://www.djcxy.com/p/67213.html

    上一篇: WCF Silverlight client getting 404 not found response for poll message

    下一篇: Start systemd service from C/C++ application or call a D