2010-10-18 102 views
3

Im建立一个自我托管的WCF服务的WPF 3.5桌面应用程序。WCF PollingDuplexHttpBinding与Silverlight客户端超时和错误

服务定义,像这样的PollingDuplexHttpBinding端点:

public static void StartService() 
    { 
     var selfHost = new ServiceHost(Singleton, new Uri("http://localhost:1155/")); 

     selfHost.AddServiceEndpoint(
      typeof(IMyService), 
      new PollingDuplexHttpBinding(PollingDuplexMode.MultipleMessagesPerPoll) {ReceiveTimeout = new TimeSpan(1,0,0,0)}, 
      "MyService" 
     ); 

     ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); 
     smb.HttpGetEnabled = true; 
     selfHost.Description.Behaviors.Add(smb); 

     selfHost.AddServiceEndpoint(typeof(IPolicyRetriever), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior()); 

     selfHost.Open(); 
    } 

注:IPolicyRetriever是使我能够定义一个策略文件

这工作,我可以看到我的服务的服务在我的客户端Silverlight应用程序中。然后我在Silverlight的代码中创建一个代理的参考,像这样:

 EndpointAddress address = new EndpointAddress("http://localhost:1155/MyService"); 

     PollingDuplexHttpBinding binding = new PollingDuplexHttpBinding(PollingDuplexMode.MultipleMessagesPerPoll); 
     binding.ReceiveTimeout = new TimeSpan(1, 0, 0, 0); 
     _proxy = new MyServiceClient(binding, address); 
     _proxy.ReceiveReceived += MessageFromServer; 
     _proxy.OrderAsync("Test", 4); 

,这也工作正常,通信工程!

但是,如果我离开它单独(即不从服务器发送的消息)的时间超过1分钟,然后尝试发送一个消息从WPF服务器应用程序的客户端,我得到超时错误,像这样:

IOutputChannel在00:01:00后试图发送超时。增加传递给发送调用的超时值或增加绑定上的SendTimeout值。分配给此操作的时间可能是超时时间的一部分。

它的所有运行在本地主机上,真的不应该有延迟,更不用说1分钟的延迟。我不知道为什么,但渠道似乎​​被关闭或丢失或东西...

我也曾尝试在绑定消除超时,我得到这样

通信对象,系统错误。 ServiceModel.Channels.ServiceChannel,不能用于通信,因为它已被中止

我如何可以尝试找出什么是错在这里吗?

回答

2

WPF使用wsDualHttpBinding,Silverlight - 轮询双面打印。 WPF解决方案很简单; Silverlight需要ServiceHostFactory和更多的代码。此外,Silverlight服务器从不发送消息,而是客户端轮询服务器并检索其消息。

PollingDuplexHttpBinding的许多问题后,我决定使用CustomBinding没有MultipleMessagesPerPoll。

的web.config

<system.serviceModel> 
    <behaviors> 
     <serviceBehaviors> 
      <behavior name="SlApp.Web.DuplexServiceBehavior"> 
       <serviceMetadata httpGetEnabled="true" /> 
       <serviceDebug includeExceptionDetailInFaults="true" /> 
      </behavior> 
     </serviceBehaviors> 
    </behaviors> 

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 

    <services> 
     <service behaviorConfiguration="SlApp.Web.DuplexServiceBehavior" name="SlApp.Web.DuplexService"> 
      <endpoint address="WS" binding="wsDualHttpBinding" contract="SlApp.Web.DuplexService" /> 
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     </service> 
    </services>  
</system.serviceModel> 

DuplexService.svc:

<%@ ServiceHost Language="C#" Debug="true" Service="SlApp.Web.DuplexService" Factory="SlApp.Web.DuplexServiceHostFactory" %> 

DuplexServiceHostFactory.cs:

public class DuplexServiceHostFactory : ServiceHostFactoryBase 
    { 
     public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses) 
     { 
      return new DuplexServiceHost(baseAddresses); 
     } 
    } 

    class DuplexServiceHost : ServiceHost 
    { 
     public DuplexServiceHost(params Uri[] addresses) 
     { 
      base.InitializeDescription(typeof(DuplexService), new UriSchemeKeyedCollection(addresses)); 
     } 

     protected override void InitializeRuntime() 
     { 
      PollingDuplexBindingElement pdbe = new PollingDuplexBindingElement() 
      { 
       ServerPollTimeout = TimeSpan.FromSeconds(3), 
       //Duration to wait before the channel is closed due to inactivity 
       InactivityTimeout = TimeSpan.FromHours(24) 
      }; 

      this.AddServiceEndpoint(typeof(DuplexService), 
       new CustomBinding(
        pdbe, 
        new BinaryMessageEncodingBindingElement(), 
        new HttpTransportBindingElement()), string.Empty); 

      base.InitializeRuntime(); 
     } 
    } 

Silverlight客户端代码:

address = new EndpointAddress("http://localhost:43000/DuplexService.svc"); 
binding = new CustomBinding(
      new PollingDuplexBindingElement(), 
      new BinaryMessageEncodingBindingElement(), 
      new HttpTransportBindingElement() 
     ); 
proxy = new DuplexServiceClient(binding, address); 
+0

对不起,延迟回复给你,谢谢你的帮助,但我不完全确定你在这里告诉我什么,我的代码工作正常,但我的连接退出,我不能停止它,你的代码会帮助这个? – Mark 2010-10-20 22:01:17

+0

我的代码没有闲置问题,我想这是因为CustomBinding没有MultipleMessagesPerPoll。无论如何,请自己尝试一下。 – vorrtex 2010-10-21 06:38:56