Eventually WCF duplex Silverlight 4 client start getting 404 Not Found
errors for poll messages, immediately after poll was send from WCF service to Silverlight client, sometimes this happens for second poll sometimes connectivity works hours or even days, but mostly fails on first minutes.
! And what is interesting the issue is like known Silverlight 4 bug when using MaxMessagesPerPoll
duplex mode and solution is described here and here but I'm using SingleMessagePerPoll
mode. ANyway I tried using ClientStack
as suggested but nothing changed.
General flow:
System.Net.WebException: The remote server returned an error: NotFound
404
response for a poll messageI'm trying to reconnect SL client after such a fault, single reconnect retry flow:
Faulted
eventClosed/Closing/Opened/Opening
try { close } catch { abort }
DuplexChannelFactory<T>
instance create a new channel, subscribe to all channel events just for logging purposesAfter 1-10 retries (~1-10 minutes) client eventually connect to a server and continue normal polling.
In WCF service log I see it get all cleint request, processed without any exception, so it seems something happens on Silverlight Client side.
var binaryBinding = new BinaryMessageEncodingBindingElement();
binaryBinding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
var httpbindingElement = new HttpTransportBindingElement
{
MaxReceivedMessageSize = 131072
};
var pollingDuplexBindingElement = new PollingDuplexBindingElement
{
ClientPollTimeout = new TimeSpan(0, 0, 1, 30),
InactivityTimeout = new TimeSpan(0, 8, 0, 0),
};
_binding = new CustomBinding(
pollingDuplexBindingElement,
binaryBinding,
httpbindingElement)
{
SendTimeout = new TimeSpan(0, 0, 0, 45),
CloseTimeout = new TimeSpan(0, 0, 0, 25),
ReceiveTimeout = new TimeSpan(0, 8, 0, 0),
OpenTimeout = new TimeSpan(0, 0, 0, 45)
};
httpbindingElement.AuthenticationScheme = AuthenticationSchemes.Negotiate;
var endpoint = new EndpointAddress(_endpointAddress);
_channelFactory = new DuplexChannelFactory<TWebService>(
new InstanceContext(instanceOfClientServiceClass),
_binding,
endpoint);
// then this factory used to create a new channels
// Also for a new channel I'm setting OpTimeout
var contextChannel = newChannel as IContextChannel;
if (contextChannel != null)
{
contextChannel.OperationTimeout = TimeSpan.FromSeconds(45);
}
All
, nothing suspicious<binding name="customName"
sendTimeout="00:01:00"
receiveTimeout="08:00:00"
openTimeout="00:01:00"
closeTimeout="00:00:35">
<pollingDuplex
inactivityTimeout="08:00:00"
serverPollTimeout="00:01:00" />
<binaryMessageEncoding />
<httpTransport authenticationScheme="Ntlm"
maxReceivedMessageSize="131072">
</httpTransport>
</binding>
<behavior name="customBehavior">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling
maxConcurrentCalls = "500"
maxConcurrentSessions = "500"
maxConcurrentInstances = "500" />
</behavior>
While investigating issue described on this StackOverflow post Static constructor called twice for PerSession WCF service I found that Polling Duplex
start working stable when I switched IIS
configuration for underlying AppPool
to use single worker process rather than 2
as was specified before. I'm not sure why 2
was set before since I do not own this server, but anyway this is what I have now - multiple Silverlight clients launched on the same machine works stable and polls polls polls and no 404
errors, all clients reconnects in 1
attempt after IIS restarts and recycles...
See Performance Application Pool Settings for more details
TL;DR: When IIS hosted WCF resides in AppPool which has more than one worker process - polling duplex becomes unstable. So in case of high load IIS started second process and start creating WCF service instances in second process as well, so I ran into situation when client session was created in one process but it seems poll sometimes reached an other process whcih is not aware of current connection/session so start refusing such messages and entire connection fault.
So Polling Duplex by design is not scalable across multiple processes in scope of a single IIS server and AppPool, in other words if you have more than 1 worker process - this is WebGarden environment and duplex is not scalable across web farms and gardens