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

How does drogon reuse existed connections? #1998

Open bethebest0622 opened 5 months ago

bethebest0622 commented 5 months ago

usually, i use HttpClient::newHttpClient as my client handler.

it it great, can reuse connections automatically.

but in my understanding, the tcp connections will be closed if long time no use.

so, how can i know if this request created connections or not (so that i can send heartbeat to keep alive)?

你好,drogon非常牛逼,本人原来使用curl,体验一言难尽。

我只使用客户端请求,并且非常在意http请求的延迟,所以我希望尽可能的保持连接被复用,并且请求函数不被阻塞

但是服务端有的时候会主动断开连接,这时候我希望我代码和日志中可以感知到连接断开,如何获取这一信息呢?

此外,我的场景,您是否有一些设置或者配置上的建议可以使之延迟更小,如果有,请不吝赐教,感谢

an-tao commented 5 months ago

目前drogon里的HttpClient,一个对象管理一个连接,断线会自动重连,请求结果在回调中返回不会阻塞当前进程,但是,该客户端是Http1.1标准,这意味着如果你一次发出多个请求,这些请求会先后到达服务端,可能不是你所说的复用。 我们有个PR实现了Http2的客户端,可以真正在一个TCP连接上同时收发多个请求和回复。但还没有合并,你可以先试试,如下:

1554

bethebest0622 commented 5 months ago

目前drogon里的HttpClient,一个对象管理一个连接,断线会自动重连,请求结果在回调中返回不会阻塞当前进程,但是,该客户端是Http1.1标准,这意味着如果你一次发出多个请求,这些请求会先后到达服务端,可能不是你所说的复用。 我们有个PR实现了Http2的客户端,可以真正在一个TCP连接上同时收发多个请求和回复。但还没有合并,你可以先试试,如下: #1554

感谢您回复,我的意思是每次调用client的时候,我希望知道该次调用是否重连(糟糕情况)或者是直接复用上次的连接成功(理想情况)。

因为重连的延迟对我来说要尽量避免,我会采取向服务端定时发送心跳的方式尽量维持这个连接不断。

另外,如果我创建一个httpclient池,里面的client host是一样的,drogon是会只创建一个连接吗?

我发现我现在使用EventLoopThreadPool GetNextLoop创建10个httpclient,并行处理10个http请求,他们立刻返回,但是回调函数收到数据据的延迟似乎是串行的,例如:(单位是微秒) 请求1调用send_request返回时间是0, 回调处理时间是30000 请求2调用send_request返回时间是10, 回调处理时间是60000 请求3调用send_request返回时间是20, 回调处理时间是90000 .。。。。

这个和我想要的并行请求似乎不符合,我希望,每个请求触发回调的时间都是30000

希望您赐教

an-tao commented 5 months ago

目前drogon里的HttpClient,一个对象管理一个连接,断线会自动重连,请求结果在回调中返回不会阻塞当前进程,但是,该客户端是Http1.1标准,这意味着如果你一次发出多个请求,这些请求会先后到达服务端,可能不是你所说的复用。 我们有个PR实现了Http2的客户端,可以真正在一个TCP连接上同时收发多个请求和回复。但还没有合并,你可以先试试,如下: #1554

感谢您回复,我的意思是每次调用client的时候,我希望知道该次调用是否重连(糟糕情况)或者是直接复用上次的连接成功(理想情况)。

因为重连的延迟对我来说要尽量避免,我会采取向服务端定时发送心跳的方式尽量维持这个连接不断。

另外,如果我创建一个httpclient池,里面的client host是一样的,drogon是会只创建一个连接吗?

我发现我现在使用EventLoopThreadPool GetNextLoop创建10个httpclient,并行处理10个http请求,他们立刻返回,但是回调函数收到数据据的延迟似乎是串行的,例如:(单位是微秒) 请求1调用send_request返回时间是0, 回调处理时间是30000 请求2调用send_request返回时间是10, 回调处理时间是60000 请求3调用send_request返回时间是20, 回调处理时间是90000 .。。。。

这个和我想要的并行请求似乎不符合,我希望,每个请求触发回调的时间都是30000

希望您赐教

每个client有自己得connection,你建10个client就应该有10个connection,他们共用1个loop也是并行发送请求的,从你描述的情况来看,说不定服务端是串行处理请求的,你可以贴一下代码,我帮你看看你写的对不对。

bethebest0622 commented 5 months ago

https://github.com/bethebest0622/http_client 请看这个仓库,我的用法是每次 创建一个HttpClient对象h 然后 h.Post(回调函数,其他http参数),万分感谢

主代码在lib_src/src/curl_tools.cpp里面

bethebest0622 commented 5 months ago

只需要看HttpClient的构造函数 和 async_execute这两个函数

an-tao commented 5 months ago

没有你说的文件啊,master分支吗

bethebest0622 commented 5 months ago

没有你说的文件啊,master分支吗

https://github.com/bethebest0622/http_client/blob/master/lib_src/src/curl_util.cpp

请看这里

an-tao commented 5 months ago

看着应该是异步的,服务端是你自己做的么

bethebest0622 commented 5 months ago

不是,服务端是 huobi 一个交易所服务器

an-tao commented 5 months ago

不是,服务端是 huobi 一个交易所服务器

你抓包看看,也许服务端串行化了;另外看看网络时延多少,估算下它处理请求花的时间;

bethebest0622 commented 5 months ago

好的,另外,我调用send_request的时候可以知道 本次请求有没有重连吗

an-tao commented 5 months ago

好的,另外,我调用send_request的时候可以知道 本次请求有没有重连吗

嗯,没有连接会重连,否则重用就连接