While using my .NET application to access TRKD services, I keep getting the following exception: “CommunicationException: The underlying connection was closed: A connection that was expected to be kept alive was closed by the server.”
Can you please tell me what is causing this and how I can resolce it when it happens?
This exception is likely to be caused by a 100 (Continue) behavior issue which happens sometimes on .NET web-service clients because of the way .NET Framework sends requests to a web-service. This is a rather known problem with .NET web-service clients and occurs not only with TRKD but it doesn't happen with all application all the time so if you are the one facing it, the below information is for you.
The purpose of the 100 (Continue) status is to allow a client that is sending a request message with a request body to determine if the origin server is willing to accept the request (based on the request headers) before the client sends the request body. In some cases, it might either be inappropriate or highly inefficient for the client to send the body if the server will reject the message without looking at the body.
In case the request is acceptable, the client receives the HTTP 100 response and then transmits the body as it had promised. The traffic for this scenario looks somewhat like this:
POST /Page HTTP/1.1
HTTP/1.1 100 Continue
HTTP/1.1 200 OK
Upon receiving a request which includes an Expect request-header field with the 100 (Continue) expectation, an origin server must either respond with 100 (Continue) status and continue to read from the input stream, or respond with a final status code. The origin server must not wait for the request body before sending the 100 (Continue) response. If it responds with a final status code, it may close the transport connection or it may continue to read and discard the rest of the request.
Closing the connection is not required in HTTP 1.1, although it may happen — say, if persistent connections are disabled altogether, the number of file descriptors reserved for persistent connections are currently exhausted, or the response doesn't contain a Content-Length header or isn't chunked.
In case a proxy gets 100 (Continue) request and knows that the version of the next-hop server is HTTP/1.0 or lower, it will not forward the request, and it will respond with a 417 (Expectation Failed) status. In order to prevent connection close from server without getting a request, therefore to avoid the .NET exception "A connection that was expected to be kept alive was closed by the server", it is possible in .NET todisable the 100 (Continue) behavior in an application. The following line should be put somewhere in the code before the initial calls occur:
System.Net.ServicePointManager.Expect100Continue = False;
Links on the subject:
• How to make a more precise adjustment: http://geekswithblogs.net/mnf/archive/2009/01/13/specify-expect100continuefalse-in-web-service-client.aspx
• HTTP 1.1. RFC 2616. Connections chapter: http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3