WCF Request Delay Every 50 Seconds - c#

I have a simple WCF service that streams images to the client. On the client, the first request for an image takes around 5.5 seconds and then subsequent requests take around 40ms, which is great.
However, after every ~45 seconds, regardless of whether any requests have been made the next request always takes around 4.6 seconds. This 45 second cycle repeats continuously.
I am using net.tcp binding with streamed transfer mode. I have also tried buffered transfer mode with/without reliable sessions enabled but all this did was increase the time taken for each request.
I have tried increasing each of the binding timeouts (open, close, send, receive, inactivity) with no change.
Server config:
serviceHost = new ServiceHost(typeof(TServiceImplementation), serviceUri);
serviceHost.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = false });
var netTCPBinding = new NetTcpBinding(SecurityMode.Transport);
netTCPBinding.TransferMode = TransferMode.StreamedResponse;
netTCPBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
serviceHost.AddServiceEndpoint(typeof(TServiceContract), netTCPBinding, ServiceName);
serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
Client config:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="TcpBinding" transferMode="StreamedResponse" maxReceivedMessageSize="2147483647" />
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://hostname:9000/StreamService"
binding="netTcpBinding" bindingConfiguration="TcpBinding" contract="StreamService.IStream"
name="NetTcpBinding_IStream" />
</client>
</system.serviceModel>
UPDATE: It looks like this might be a machine specific issue - when I run the service on my local machine I do not experience this issue.

Ok, so a bit more investigation and I have determined that this was an address resolution issue - The actual images were hosted on a different machine to the one running the service so I changed the config to use the IP address of the host rather than the computer name and the problem was resolved.
I'm guessing this has something to do with a name cache timeout but not looked into which one it could be yet.

Related

"Could not get any response" from WCF service using secure bindings, timeout settings ignored?

I have a service on a remote machine using secure bindings. All of my service configurations are in config files (and I have checked to make sure the right config files are being adjusted.) I have tried to tell the service to timeout at 3 minutes, but every time I make a request that takes longer than a minute, Postman gives me the generic "Could not get any response" page. (It doesn't even give me an error or a stack trace.) This happens exactly at 1 minute. Yes, I even used the stopwatch on my phone to verify it's exactly a minute.
In a different environment that uses non-secure bindings, I know this particular call takes about 90 seconds. I just need this secure environment to wait a little longer!
I'm sorry if my jargon isn't on key, I'm slightly new at this.
My services config file for the WCF service in question looks like this:
<service name="XXX.SolrIndexService.Host.Services.EventIndexService">
<endpoint address="ajax"
behaviorConfiguration="ServerReadCookie"
binding="webHttpBinding"
bindingConfiguration="webHttpsBinding"
contract="XXX.SolrIndexService.DataContracts.IEventIndexService" />
</service>
The actual binding configuration is here:
<webHttpBinding>
<binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true">
<security mode="None" />
</binding>
<binding name="webHttpBindingUnsecure" crossDomainScriptAccessEnabled="true">
<security mode="None" />
</binding>
<binding name="webHttpsBinding" crossDomainScriptAccessEnabled="true"
closeTimeout="00:03:00"
openTimeout="00:03:00"
receiveTimeout="00:10:00"
sendTimeout="00:03:00">
<security mode="Transport" />
</binding>
</webHttpBinding>
These are snippets from the entire configs file, I can post the whole thing if anyone thinks that would be helpful. I also used XXX in place of the client's name just because I'm not sure what the etiquette is with that sort of thing.
I've seen lots of posts regarding WCF timeouts and my general impression is that they're mysterious and picky. I've also checked IIS limits for the site that hosts the service, and it has a general Connection Timeout setting of 120 seconds.
Thanks!
Rather than using postman you should use the WCF Client tool
this might give you more feedback
Turns out in my particular case I was hitting my service through a load balancer. I did not attempt to change any settings on the load balancer. Instead I decided to hit the service using the specific machine that it was hosted on. After doing that, my timeout settings were obeyed and I'm no longer timing out before the call can be completed.
I'm not sure if that will help anyone in the future, it's rather specific, but you never know.

WCF: Identical config file on server and client side?

My WCF service hang randomly. when I try to debug using Microsoft Service Trace Viewer I found out I was getting
The socket connection was aborted. This could be caused by an error
processing your message or a receive timeout being exceeded by the
remote host, or an underlying network resource issue. Local socket
timeout was '00:01:00'.
Therefore I change the "receiveTimeout" in the Net pipe binding section (server side) like this.
Server side
<netNamedPipeBinding>
<binding name="myPipeBinding"
receiveTimeout="24:0:0">
</binding>
</netNamedPipeBinding>
And then I try to update the config file of the client using the Visual Studio 2013 "Update Service Reference". It give me the new App.config in the client side like this.
<bindings>
<netNamedPipeBinding>
<binding name="NamedPipedService" />
</netNamedPipeBinding>
</bindings>
<client>
<endpoint address="net.pipe://localhost/Server" binding="netNamedPipeBinding"
bindingConfiguration="NamedPipedService" contract="WCFService.IServer"
name="NamedPipedService">
<identity>
<userPrincipalName value="Server\MyComputer" />
</identity>
</endpoint>
</client>
I thought everything work but my service crash again with the same error. So I thought "receiveTimeout" section of the "netNamedPipeBinding" should also be added in the client's App.config file. My question is
Is the error I am getting due to default timeout value of Net pipe binding?
Should I set the receiveTimeout value (server side) ?
Do I also need to change the App.config file in the client side for the changes to take effect? Since updating by Visual Studio 2013 does not add the receiveTimeout section.

WCF service call returns '407 Proxy Authentication Required'

I am hosting a WCF webservice (on Azure) and have shipped a WPF desktop application to a client who (obviously) tries accessing the service through a proxy.
The service calls fails, returning
The remote server returned an unexpected response: 407 Proxy
Authentication Required
The ServiceModel section of the client app.config file looks like this:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ILicensing" closeTimeout="00:00:15" openTimeout="00:00:15"
receiveTimeout="00:00:15" sendTimeout="00:00:15" maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="xxxxxxx"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ILicensing"
contract="Cloud.ILicensing" name="BasicHttpBinding_ILicensing" />
</client>
</system.serviceModel>
That's basically all I know.
I would know like to fix this behavior by modifying the app.config file and/or the web.config file of the service (which shouldn't matter, as the service is not reached anyways).
As far as I have understood, there is the attribute useDefaultWebProxy of the binding node, which asks to look up the system proxy configuration and use this for connecting to the service. However, as the default value is true, I would expect that setting it to true explicitly doesn't change anything (that's basically the definition of a default, I guess).
What can be reasons for the failing proxy authentication, considering useDefaultWebProxy is not set and therefor should be true due to it's default value?
How can the app.config be modified in order to fix the issue considering the limitied information? Basically: What do I need to know/ask my client (i.e. proxy server address) and where do I need to insert the information in my client config file?
How can I set up a test environment on my local machine which mimics the issue?
For 1 and 2, you need to configure System.Net to provide default credentials for the default proxy - it doesn't do this by default (because hidden callback code in apps with automatic access to the internet would be bad).
<system.net>
<defaultProxy useDefaultCredentials="true" />
</system.net>
For 3, I'm not entirely sure how you would be able to test this locally as you need a machine to act as the proxy and these are typically domain controller type machines. You could simulate with 2 VMs but I hope you have a powerful machine in order to do so plus it seems like a lot of effort to test this.
You can do it from code
WebRequest.DefaultWebProxy.Credentials = CredentialCache.DefaultNetworkCredentials;

maintaining user session on WCF Clients while making calls to servers behind a load balance

My problem is the following:
- I have a .Net MVC site making a lot of calls to WCF services hosted in two server behind a load balancing server (BIGip).
I do have to maintain a user session on the WCF services (controlled by a custom token).
My problem is that the sticky session is not working when a lot of users is logged on the site (a lot of concurrent calls to the services).
What I figured out was that when the site calls the service reusing a existing connection, the load balancing server ignores the sticky session cookie and forwards the request to the last server that received a call by this connection.
I checked using sniffer (Wireshark), and every call is sent to the load balancing server with the correct sticky session token.
When a connection is created from scratch the stick session cookie is taken into account and the request goes to the right server.
So, how can I handle that situation?
I'm looking for something that enforces creating a new connection on each call, but the property KeepAliveEnabled="false" is not working.
Tks.
My problem was solve using the correct keepAliveConnection configuration to Framework 4.
Bellow are the configs.
The wrong one
<bindings>
<customBinding>
<binding name="WSHttpBinding_IServiceSessionCreator" keepAliveEnabled="false">
<httpTransport />
</binding>
</customBinding>
</bindings>
The correct one
<bindings>
<customBinding>
<binding name="WSHttpBinding_IServiceSessionCreator" >
<textMessageEncoding />
<httpTransport allowCookies="false" keepAliveEnabled="false"/>
</binding>
</customBinding>
</bindings>
I don't know why the first one did not work.
I saw it in this link http://msdn.microsoft.com/en-us/library/vstudio/ms730128(v=vs.100).aspx

WCF & keepAliveEnabled - More than two sockets at the same time?

I try to make a multiple-thread requester in order to test answer time of my server.
My server is a WCF webservice, and my client has a service reference to this webservice.
WCF respect HTTP specifications, and I see on many websites WCF is Keep-Alive enabled by default. By only two connections from the same client are authorized at same time.
So, when I try to create 100 threads, only two of them are processing at the same time. So, after few loops, a lot of threads are in timeout.
I try to follow this article : WCF wsHttpBinding with http keepalive but it didn't work.
Here is my app config (modified by the Service Reference) :
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ISabIn" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://xxx.xxx.xxx.xxx:xxx/SabIn.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_ISabIn" contract="TestWs.ISabIn"
name="BasicHttpBinding_ISabIn" />
</client>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
I try to use customBinding in the appCode, like this article : HTTP Keep-alive and ServiceHost / C#?
but, when I execute my software, an erreor appears about "application/xml". If I try to translate in english, it would be somehting like "your client don't manage the application/xml message".
I need to do real-time transactions, and I can't if WCF only manage two sockets at same time...
Can you help me ?
PS : I can post the code of my client, but I'm not sure is useful since I know the problem is a sockets limitation.
SOLUTION (thnaks to Spender) : at the beginning of your code, change the default value (it is 2) in System.Net.ServicePointManager.DefaultConnectionLimit
Isn't this caused by default .net limits on HTTP request to a single host? This is because ServicePointManager.DefaultConnectionLimit defaults to 2.
When you issue an HTTP request, internally, a ServicePoint instance is created to manage the connections to a specific host. Make a new request to the same host, and it will use the same ServicePoint instance for connection management.
You can manipulate the limit for a single host with the following code:
var serviceUri = new Uri("http://xxx.xxx.xxx.xxx:xxx/SabIn.svc");
var servicePoint = System.Net.ServicePointManager.FindServicePoint(serviceUri);
servicePoint.ConnectionLimit = int.MaxValue;
I believe you can also handle this in web.config/app.config but I'm not sure if you can tweak limits associated with a single ServicePoint.

Categories