Im building a WPF 3.5 desktop app that has a self-hosted WCF service.
The service has an PollingDuplexHttpBinding endpoint defined like so:
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
This works and I can see my service in my client Silverlight application. I then create a reference to the proxy in the Silverlight code like so:
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:
The IOutputChannel timed out attempting to send after 00:01:00. Increase the timeout value passed to the call to Send or increase the SendTimeout value on the Binding. 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. 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
How can I try to find out whats wrong here?
WPF uses wsDualHttpBinding, Silverlight - Polling Duplex. WPF solution is simple; Silverlight requires ServiceHostFactory and a bit more code. Also, Silverlight Server never sends messages, rather Client polls the server and retrieves its messages.
After many problems with PollingDuplexHttpBinding I have decided to use CustomBinding without 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 client code:
address = new EndpointAddress("http://localhost:43000/DuplexService.svc");
binding = new CustomBinding(
new PollingDuplexBindingElement(),
new BinaryMessageEncodingBindingElement(),
new HttpTransportBindingElement()
);
proxy = new DuplexServiceClient(binding, address);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.