【问题标题】:WCF PollingDuplexHttpBinding with Silverlight Client timeouts and errorsWCF PollingDuplexHttpBinding 与 Silverlight 客户端超时和错误
【发布时间】:2010-10-18 02:22:55
【问题描述】:

我正在构建一个具有自托管 WCF 服务的 WPF 3.5 桌面应用程序。

服务有一个 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 之后尝试发送超时。增加传递给 Send 调用的超时值或增加 Binding 上的 SendTimeout 值。分配给此操作的时间可能是较长超时的一部分。

它全部在 localhost 上运行,真的不应该有延迟,更不用说 1 分钟的延迟了。我不知道为什么,但是频道似乎被关闭或丢失或什么的......

我也尝试过删除绑定的超时,但我得到了这样的错误

通信对象 System.ServiceModel.Channels.ServiceChannel 已被中止,无法用于通信

我怎样才能找出这里出了什么问题?

【问题讨论】:

    标签: wpf silverlight wcf


    【解决方案1】:

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

    在 PollingDuplexHttpBinding 出现许多问题后,我决定使用不带 MultipleMessagesPerPoll 的 CustomBinding。

    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);
    

    【讨论】:

    • 抱歉延迟回复您,感谢您的帮助,但我不太确定您在这里告诉我的确切内容,我的代码工作正常,但我的连接中断,我无法阻止它,您的代码会对此有所帮助吗?
    • 我的代码没有不活动的问题,我认为这是因为没有 MultipleMessagesPerPoll 的 CustomBinding。不管怎样,你自己试试吧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多