how to set httpclient connect timeout? - c#

I'm struggling with setting connect timeout with c# HttpClient or its siblings (HttpClientHandler,WebRequestHandler,...) . There's a timeout property in HttpClient, but it seems to be a timeout from the beginning of the request until receiving the response. I want to have a method which specify that for example if you don't received ACK from the net socket within 10 seconds for example , then break up and do the next.
I saw that there may be something similar in WinHttpHandler class, but it seems to be deleted or not available in recent version. compare the first link vs second :
1.WinHttpHandler MSDN
2.WinHttpHandler Microsoft Docs
I really need this, because I must differentiate asap between IP's which have a working web servers (maybe slow) vs which don't have a web server at all.

I use HttpWebRequest.Timeout in my project to verdict the connection time before establish tcp connection. And use HttpWebRequest.ReadOrWriteTimeout to verdict whole response timeout.
Ps: The HttpClient seems cut off some useful properties.

Related

WCF request returns wrong response

I have a c# application that the client uses wcf to talk to the server. In the background every X seconds the client calls a Ping method to the server (through WCF). The following error has reproduced a couple of times (for different method calls):
System.ServiceModel.ProtocolException: A reply message was received for operation 'MyMethodToServer' with action 'http://tempuri.org/IMyInterface/PingServerResponse'. However, your client code requires action 'http://tempuri.org/IMyInterface/MyMethodToServerResponse'.
MyMethodToServer is not consistent and it falls on different methods.
How can this happen that a request receives a different response?
I think you have a pretty mess problem with async communication, main suggestion (as your question isn't clear very well), is try to identify every request, catch the calls and waiting for them, do asyncronic communication and getting a several work with threading.
As you present it, is a typical architecture problem.
If you present more code, can I suggest some code fixing in my answer and I'll be glad to update my answer.
If this occurs randomly and not you consistently, you might be running in a load-balanced setup, and deployed an update to only one of the servers?
Wild guess: your client uses same connection to do two requests in parallel. So what happens is:
Thread 1 sends request ARequest
Thread 2 sends request BRequest
Server sends reply BReply
Thread 1 receives reply BReply while expecting AReply
If you have request logs on the server, it'll be easy to confirm - you'll likely see two requests coming with short delay from the client host experiencing the issue
I think MaxConcurrentCall and ConcurrencyMode may be relevant here (although I did not touch WCF for a long while)

Adjust HttpRequst Timeout Before Creating any HttpWebRequest

In C# 5 and winform, I used a library created by Telegram Company. In this library there is a function SendDocument(UserId,DocumentStream). I know in this function, they used some HttpWebRequest, and the Timeout property of that is not handled. because sometimes it can't send large documents and after exact 100 seconds(default timeout in DotNet), the function throws an exception The task was canceled.
From the document of Telegram Company, we can send 50 MB files and my example files is about 15 MB.
Ok, Now I want to adjust the timeout of all HttpWebRequest of my server but I don't have any feature for this.
Can I adjust all HttpWebRequest.Timeout property in my server??
This is not directly related to your question, but may help ease your mind.
My advice is, don't bother adjusting the timeout. It is not likely to help. Here is what I have gone through:
I have tried to upload a 20M mp4 video file using Telegram Bot API. From a Raspberry Pi, it took 5 minutes, then returned a 504 Gateway-Timeout error. From a hosted server, it took 1 minute, then returned a 504 Gateway-Timeout error. In both cases, however, the video did eventually reach the recipient 5 minutes later. So, the upload seemed somewhat successful, yet not quite successful.
I tried to fix the problem by streaming the upload. Same problem persisted.
I tried to adjust the HTTP timeout parameter. Same problem persisted.
I tried to use cURL to make the request (instead of using telepot, a Python library I author). Same problem persisted.
I suspect the problem lies with the Telegram servers, so I talked to Bot Support. They got back to me once, saying they have made some improvements and asked if I still have the same problem. But same problem still persists.
So, it seems the problem does lie with the Telegram servers. It's not your code.
I know it's a pretty old question but may be my answer will help somebody. When I tried to send cosiderably large files via my bot I received Telegram.Bot.Exceptions.ApiRequestException: Request timed out and the only solution I found was this issue. Which wasn't really helpfull because if you check source code then you'll see that passing cancellation token does nothing with request timeout. But then I saw that you can pass HttpClient to your bot client instance and make it something like this:
_httpClient = new HttpClient();
_httpClient.Timeout = new TimeSpan(0, 5, 0); // 5 min
_client = new TelegramBotClient(botConfig.Token, _httpClient);
Hope this will help

What is different in the .NET (c#) implementation of webclient versus java or firefox RESTClient?

I need to post JSON to a https endpoint using c# .
I am using System.Net.WebClient (or HttpWebRequest ).
When I post the JSON to the endpoint using JAVA or the firefox RESTClient everything works fine (from the same machine).
With Wireshark I can see that the receiving server RESETs the connection, resulting in this .NET exception:
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
I don't use any proxy servers.
I have set the request timeout to -1 (and other values).
What can the .NET runtime be adding to (or removing from) the requests that the firefox RESTPlugin en JAVA are not ?
There must be a difference.
Fiddler shows me two http(s) requests with response status 200, but no data seems to be coming back (and Fiddler introduces a proxy...)
#Mason thanks for making me look once more at the fiddler data.
After setting the protocol to TLS1.2
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
It works.
I have seen posts that actual get an error message hinting at the minimal TLS support. But here I had to go through StackOverflow first.
Just the exercise of formulating the question and the first quick responders helpt me fix this quickly !

WCF client hangs on response

I have a WCF client (running on Win7) pointing to a WebSphere service.
All is good from a test harness (a little test fixture outside my web app) but when my calls to the service originate from my web project one of the calls (and only that one) is extremely slow to deserialize (it takes minutes VS seconds) and not just the first time.
I can see from fiddler that the response comes back quickly but then the WCF client hangs on the response itself for more than a minute before the next line of code is hit by the debugger, almost if the client was having trouble deserializing. This happens only if in the response I have a given pdf string (the operation generates a pdf), base64 encoded chunked. If for example the service raises a fault (thus the pdf string is not there) then the response is deserialized immediately.
Again, If I send the exact same envelope through Soap-UI or from outside the web project all is good.
I am at loss - What should I be looking for and is there some config setting that might do the trick?
Any help appreciated!
EDIT:
I coded a stub against the same service contract. Using the exact same basicHttpBinding and returning the exact same pdf string there is no delay registered. I think this rules out the string and the binding as a possible cause. What's left?
Changing transferMode="Buffered" into transferMode="Streamed" on the binding did the trick!
So the payload was apparently being chunked in small bits the size of the buffer.
I thought the same could have been achieved by increasing the buffersize (maxBufferSize="1000000") but I had that in place already and it did not help.
I have had this bite me many times. Check in your WCF client configuration that you are not trying to use the windows web proxy, that step to check on the proxy (even if there is not one configured) will eat up a lot of time during your connection.
If the tips of the other users don't help, you might want to Enable WCF Tracing and open it in the Service Trace Viewer. The information is detailed, but it has enabled me to fix a number of hard-to-identity problems in the past.
More information on WCF Tracing can be found on MSDN.
Two thing you can try:
Adjust the readerQoutas settings for your client. See http://msdn.microsoft.com/en-us/library/ms731325.aspx
Disable "Just My Code" in debugging options. Tools -> Options -> Debugging -> General "Enable Just My Code (Managed only)" and see if you can catch interal WCF exceptions.
//huusom
I had the very same issue... The problem of WCF, IMO, is in the deserialization of the base64 string returned by the service into a byte[] client side.
The easiest to solve this if you may not change your service configuration (Ex.: use a transferMode="Streamed") is to adapt your DataContract/ServiceContract client side. Replace the type "byte[]" with "string" in the Response DataContract.
Next simply decode the returned string yourself with a piece of code such as:
byte[] file = Convert.FromBase64String(pdfBase64String);
To download a PDF of 70KB, it used to required ~6 sec. With the suggested change here above, it takes now < 1 sec.
V.
PS.: Regarding the transfer mode, I did try to only change the client side (transferMode="StreamedResponse") but without improvement...
First things to check:
Is the config the same in the web project and the test project?
When you test from SOAP UI are you doing it from the same server and in the same security context as when the code is running from the web project.
-Is there any spike in the memory when the pdf comes back?
Edit
From your comments the 1 min wait, appears that it is waiting for a timeout. You also mention transactions.
I am wondering if the problem is somewhere else. The call to the WCF service goes OK, but the call is inside a transaction, and there is no complete or dispose on the transaction (I am guessing here), then the transaction / code will hang for 1 min while it waits to timeout.
Edit 2
Next things to check:
Is there any difference in the code is the test and in the web project, on how the service is being called.
Is there any differnce in the framework version, for example is one 3.0 and the other 3.5
Can it be that client side is trying to analyse what type of content is coming from server side? Try to specify mime type of the service response explicitly on the server side, e.g. Response.ContentType = "application/pdf" EDIT: By client side I mean any possible mediator like a firewall or a security suite.

Using .NET's HttpWebRequest to download a multitude of files in a row

I have an application that needs to download several files in a row in succession (sometimes a few thousand). However, what ends up happening when several files need to be downloaded is I get an exception with an inner exception of type SocketException and the error code 10048 (WSAEADDRINUSE). I did some digging and basically it's because the server has run out of sockets (and they are all waiting for 240s or so before they become available again) - not coincidentally it starts happening around the 1024 file range. I would expect that the HttpWebRequest/ServicePointManager would be reusing my connection, but apparently it is not (and the files are https, so that may be part of it). I never saw this problem in the C++ code that this was ported from (but that doesn't mean it didn't ever happen - I'd be surprised if it was, though).
I am properly closing the WebRequest object and the HttpWebRequest object has KeepAlive set to true by default. Next my intent is to fiddle around with ServicePointManager.SetTcpKeepAlive(). However, I can't see how more people haven't run into this problem.
Has anyone else run into the problem, and if so, what did you do to get around it? Currently I have a retry scheme that detects this error and waits it out, but that doesn't seem like the right thing to do.
Here's some basic code to verify what I'm doing (just in case I'm missing closing something):
WebRequest webRequest = WebRequest.Create(uri);
webRequest.Method = "GET";
webRequest.Credentials = new NetworkCredential(username, password);
WebResponse webResponse = webRequest.GetResponse();
try
{
using(Stream stream = webResponse.GetResponseStream())
{
// read the stream
}
}
finally
{
webResponse.Close()
}
What kind of application is this? You mentioned that the server is running out of ports, but then you mentioned HttpWebRequest. Are you running this code in a webservice or ASP.NET page, which is trying to then download multiple files for the same incoming request from the client?
What kind of authentication is the page using? If it is using NTLM authentication, then the connections cannot be shared if the credentials being used are different for each request.
What I would suggest is to group your request per credential. So, for eg, all requests using username "John" would be grouped. You can specify the "ConnectionGroupName" property on the service point, so the system will try to reuse connections for the same credential and server.
If that also doesnt work, you will need to do one or more of the following:
1) Throttle your requests.
2) Increase the wildcard port range.
3) Use the BindIPConnectionCallback on ServicePoint to make it bind to a non-wildcard port (i.e a port in the range 1024-16384)
More digging seems to point to it possibly being due to authentication and the UnsafeAuthenticatedConnectionSharing property might alleviate this. However, I'm not sure that's the best thing, either.

Categories

Resources