2010-10-18 75 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