简体   繁体   English

WCF PollingDuplexHttpBinding与Silverlight客户端超时和错误

[英]WCF PollingDuplexHttpBinding with Silverlight Client timeouts and errors

Im building a WPF 3.5 desktop app that has a self-hosted WCF service. 我正在构建一个具有自托管WCF服务的WPF 3.5桌面应用程序。

The service has an PollingDuplexHttpBinding endpoint defined like so: 该服务具有如下定义的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();
    }

Note: the IPolicyRetriever is a service that enables me to define a policy file 注意:IPolicyRetriever是一种允许我定义策略文件的服务

This works and I can see my service in my client Silverlight application. 这有效,我可以在我的客户端Silverlight应用程序中看到我的服务。 I then create a reference to the proxy in the Silverlight code like so: 然后我在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);

And this also works fine, the communication works! 这也很好,通讯工作!

But if I leave it alone (ie dont sent messages from the server) for longer than 1 minute, then try to send a message to the client from the WPF server application, I get timeout errors like so: 但如果我不管它(即不要从服务器发送消息)超过1分钟,然后尝试从WPF服务器应用程序向客户端发送消息,我会收到超时错误,如下所示:

The IOutputChannel timed out attempting to send after 00:01:00. IOutputChannel在00:01:00之后尝试发送超时。 Increase the timeout value passed to the call to Send or increase the SendTimeout value on the Binding. 增加传递给Send的调用的超时值或增加Binding上的SendTimeout值。 The time allotted to this operation may have been a portion of a longer timeout. 分配给此操作的时间可能是较长超时的一部分。

Its all running on localhost and there really should not be a delay, let alone a 1 minute delay. 它全部运行在localhost上,确实不应该有延迟,更不用说延迟1分钟了。 I dont know why, but the channel seems to be closed or lost or something... 我不知道为什么,但频道似乎关闭或丢失或某事......

I have also tried removing the timeouts on the bindings and I get errors like this 我也尝试删除绑定上的超时,我得到这样的错误

The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it has been Aborted 通信对象System.ServiceModel.Channels.ServiceChannel不能用于通信,因为它已被中止

How can I try to find out whats wrong here? 我怎样才能在这里找出错误的信息?

WPF uses wsDualHttpBinding, Silverlight - Polling Duplex. WPF使用wsDualHttpBinding,Silverlight - Polling Duplex。 WPF solution is simple; WPF解决方案很简单; Silverlight requires ServiceHostFactory and a bit more code. Silverlight需要ServiceHostFactory和更多代码。 Also, Silverlight Server never sends messages, rather Client polls the server and retrieves its messages. 此外,Silverlight Server从不发送消息,而是客户端轮询服务器并检索其消息。

After many problems with PollingDuplexHttpBinding I have decided to use CustomBinding without MultipleMessagesPerPoll. 在使用PollingDuplexHttpBinding的许多问题之后,我决定使用不带MultipleMessagesPerPoll的CustomBinding。

web.config 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: DuplexService.svc:

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

DuplexServiceHostFactory.cs: 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 client code: Silverlight客户端代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM