TCP Connections and Web Service Calls (Reposted from WebServices newsgroup)
Hi Everyone, I have a windows service which consumes a web service on a separate machine in our network. I modified my machine.config to allow my service application to make 200 connections to the server at once, and I spool up to 200 threads at once to make calls to the server. All of this works great and as expected. However I have noticed that by default the underlying connections tend to stay open for about 90 seconds after my web service calls terminate. So if I use a tool like TCPView I can see that I still have hundreds of connections that remain open even after explicitly calling the .Dispose() method of my proxy objects. Is there a way that I can force those connections to close from my Service? Or is that controlled by the server?
Durgaprasad Gorti told me I could get into MaxIdleTime setting and set it's timeout to something small like 3000 to force the connection close...however the conetex of the example which was provided troubled me.
'example
Request.FindServicePoint().MaxIdleTime = 3000; //3 seconds
I'm not 100% sure what was meant by Request, so I put the following code into my service:
ServicePoint MySP;
MySp = ServicePointManager.FindServicePoint(new System.Uri(http://SomeServerOnMyNetwork));
MySp.MaxIdleTime = 1000;
While this 'seems' to do the trick I'm a bit confused as to how far reaching the FindServicePoint method is. Will it only seek them from the current running application domain, or is it system wide. Because I have other windows services running at the same time connected to seperate web services on the same server, which I do not want to break.
Is there a way from the proxy object itself to get the endpoints and close them?
Thanks a Million.
John Rossitter
I would suggest that instead of using ServicePointManager.FindServicePoint you should instead override the web service base class function 'GetWebRequest' to gain access to the underlying HttpWebRequest (see code snippet below). This helps to ensure that you are using the correct service point because your code above doesn't take into account proxy settings and could end up giving you the wrong ServicePoint.
Also, if you really want to force the connection to close when you are done, you should set HttpWebRequest.KeepAlive = false instead of using the MaxIdleTime. Keep in mind that opening and closing a large number of connections to the same ServicePoint in a short period of time has consequences. Please read http://blogs.msdn.com/dgorti/archive/2005/09/18/470766.aspx for information about the types of issues you should be aware of when designing your app.
| |
public partial class Service1 : System.Web.Services.Protocols.SoapHttpClientProtocol { protected override WebRequest GetWebRequest(Uri uri) { WebRequest request = base.GetWebRequest(uri); //cast it to an HttpWebRequest, if it isn't null //then the type cast was successful HttpWebRequest httpRequest = request as HttpWebRequest; if(httpRequest != null) { httpRequest.ServicePoint.MaxIdleTime = 3000; httpRequest.KeepAlive = false; } return request; } //...a bunch of other code has been trimmed out... }
|
The file typically resides under a sub folder for your Visual studio project. Look under something like <you project folder>\web references\<webservice Name>\reference.vb
(file and folder names may not be exactly as I describe, this should point you in the right direction).
| |
Public Overloads Function GetWebRequest(ByVal requestUri As Uri) As System.Net.WebRequest Dim request As System.Net.HttpWebRequest = CType(MyBase.GetWebRequest(requestUri), System.Net.HttpWebRequest) 'do something with the request, tweak some properties, etc. Return request End Function
|
Thank you for your answer.
But neither Override nor Overloads works with .NET Framework 1.1 and .NET Framework 2.0 Beta 2 if I use a seperate class. Then I cannot override or overload the proxy class method GetWebRequest.
If I add the Function GetWebRequest to the proxy class it works with .NET 1.1 and .NET 2.0 Beta 2.
Visual Web Developer Express doesn't add the proxy file to the App_WebReferences folder in the project.
If you don't want to go through this, a simpler alternative is to set
ServicePointManager.MaxServicePointIdleTime to 1000 milliseconds
if the connection is idle for more than a second it will close the connection.
For this you don't need to look for the proxy class