drogonframework / drogon

Drogon: A C++14/17/20 based HTTP web application framework running on Linux/macOS/Unix/Windows
MIT License
11.44k stars 1.1k forks source link

Why I use c# and cpp http client to call an hello world drogon api and the time spend 2s per a call? #1745

Closed zzfzzf1018 closed 1 year ago

zzfzzf1018 commented 1 year ago

Describe the bug I create a drogon project and write a simple API to return "hello world" image then use both c# and cpp HTTP client to call this API, it spends 2s per a call. but use browser to call this API, the time is ok (between 1ms~6ms) (drogon 1.8.4)

To Reproduce Steps to reproduce the behavior:

  1. Create an empty drogon project using drogon_ctl
  2. add a controller, it implement the HttpSimpleController
  3. add PATH_ADD("/test", Get);
  4. add below to return hellow world
    //write your application logic here
    auto resp = HttpResponse::newHttpResponse();
    //NOTE: The enum constant below is named "k200OK" (as in 200 OK), not "k2000K".
    resp->setStatusCode(k200OK);
    resp->setContentTypeCode(CT_TEXT_HTML);
    resp->setBody("Hello World!");
    callback(resp);
  5. Build in windows MSVC solution using release mode
  6. Run
  7. Write a c# or cpp console to call this API and record time

Expected behavior It should the same spend time by using browser

Screenshots image

Desktop (please complete the following information):

Additional context Using c#/cpp/python client have the same issue, but use the nodejs and browser is ok

VladlenPopolitov commented 1 year ago

Hi! What exactly you did in step 8? I understood everything before and after, but not this: 8. Write a c# or cpp console to call this API and record time

zzfzzf1018 commented 1 year ago

Hi! What exactly you did in step 8? I understood everything before and after, but not this: 8. Write a c# or cpp console to call this API and record time

I use c# HTTP CLIENT and c++ httplib.h. I found that if I use cli.set_keep_alive(true); when using c++ httplib, it will works fine except the first request. Also in c# httpclient(its default keep alive true), previously I test the each request with new HttpClient each time. after I change it to only init HttpClient one time, the request will also normally except the first request.

It seems the build the Http connection spends more time(2s)?

zzfzzf1018 commented 1 year ago

image

VladlenPopolitov commented 1 year ago

Can you try access by curl (usual C client) or wget (also C client)? You also need to check firewall settings on your PC. Two weeks ago was some bug in trantor and it was fixed. Probably you have this version. Try latest trantor from GitHub master HEAD.

zzfzzf1018 commented 1 year ago

Can you try access by curl (usual C client) or wget (also C client)? You also need to check firewall settings on your PC. Two weeks ago was some bug in trantor and it was fixed. Probably you have this version. Try latest trantor from GitHub master HEAD.

We tried the 1.8.6 pre-release, the issue is still. we try use curl and find that the curl is ok. But if we use c#, it still need about 2s for the first HTTP connection. (Windows defender firewall disabled)

using System.Diagnostics;

using (HttpClient client = new HttpClient())
{
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Restart();
    HttpRequestMessage msg = new HttpRequestMessage();
    //http://localhost/test
    msg.RequestUri = new Uri("http://localhost:9988/");
    var res = client.Send(msg);
    stopwatch.Stop();
    //Console.WriteLine(res.Content);
    Console.WriteLine(stopwatch.ElapsedMilliseconds);
}
Console.ReadLine();

image

The very strange thing is, the log from drogon seems everything is ok (see above drogon logs)?

an-tao commented 1 year ago

You can utilize Wireshark to capture network packets and decipher the situation.

zzfzzf1018 commented 1 year ago

MicrosoftTeams-image (1)

any ideas? I am not familiar with TCP protocol.

an-tao commented 1 year ago

Your client tries IPV6 address first. You can add ipv6 listener to your drogon server.

zzfzzf1018 commented 1 year ago

Your client tries IPV6 address first. You can add ipv6 listener to your drogon server.

after add ipv6 listener in drogon server or force ipv4 in client, the issue solved,

thank you very much~