THttpClient中KeepAlive工作机制及连接复用场景咨询
Let's break down your two scenarios and clarify the behavior across Android, iOS, and Windows platforms, plus how to test this on mobile devices.
Scenario 1: Reusing the Same THttpClient Instance
MyHttpClient := ThttpClient.create; MyHttpClient.Get('https://www.siteA.com'); MyHttpClient.Get('https://www.siteB.com'); MyHttpClient.Get('https://www.siteA.com');
Here's what plays out on each platform:
- Windows: THttpClient relies on WinHTTP under the hood, which automatically manages connection pooling with KeepAlive enabled by default. The first request to
siteAestablishes the full connection (including HTTPS handshake), thesiteBrequest uses a new connection, and the secondsiteArequest will reuse the existing pooled connection (as long as the KeepAlive timeout—usually a few minutes—hasn't expired). - Android: THttpClient uses the system's HttpURLConnection, which supports connection pooling out of the box. As long as you're using the same client instance, the second request to
siteAwill reuse the already established connection (skipping the HTTPS handshake entirely) after the detour to siteB. - iOS: On iOS, THttpClient wraps NSURLSession, which maintains a connection pool tied to each session. Since you're using the same client instance (and thus the same session), the second
siteArequest will reuse the connection created in the first call.
The core takeaway here is that a single THttpClient instance retains access to the platform's connection pool, so repeated requests to the same host can reuse connections when conditions allow.
Scenario 2: Using Separate THttpClient Instances
MyHttpClient1 := ThttpClient.create; MyHttpClient1.Get('https://www.siteA.com'); MyHttpClient1.disposeOf; MyHttpClient2 := ThttpClient.create; MyHttpClient2.Get('https://www.siteA.com'); MyHttpClient2.disposeOf;
Disposing the client instance cleans up its associated resources, so this changes everything:
- Windows: When you dispose
MyHttpClient1, WinHTTP closes the connection pool linked to that client.MyHttpClient2creates a brand new pool, so the second request tositeAwill establish a full new connection and HTTPS handshake. - Android: Disposing
MyHttpClient1shuts down the HttpURLConnection's connection pool for that client.MyHttpClient2spins up a fresh pool, so the second request will perform a complete new connection and handshake. - iOS: NSURLSession's connection pool is tied directly to the session instance. Disposing
MyHttpClient1invalidates its underlying session, soMyHttpClient2creates a new session with a blank pool. The second request tositeAwill need to establish a new connection and handshake from scratch.
In short, separate THttpClient instances can't share connection pools, so each request here starts from zero.
Testing KeepAlive Behavior on Android/iOS
To confirm whether connections are being reused (and avoid redundant handshakes), try these practical methods:
- Network Traffic Analysis:
- On Android: Use Android Studio's Network Profiler to capture HTTP traffic. Look for the
Connectionheader in requests and responses—ifKeep-Aliveis present, check if subsequent requests to the same host use the same connection ID. Reused connections will skip the SSL handshake step entirely. - On iOS: Use Xcode's Network Inspector (in the Debug area) to monitor requests. Check the "Connection" tab for each request—reused connections will show the same identifier, and you won't see a new SSL handshake log entry.
- On Android: Use Android Studio's Network Profiler to capture HTTP traffic. Look for the
- Log SSL Handshakes:
- For Android: Enable debug logging for the system's SSL stack via JNI bridge or a helper class. You can add code to log when handshakes start, then check if the second
siteArequest triggers a new log entry. - For iOS: Add the argument
-NSNetworkLogLevel 3to your Xcode run scheme. This will output detailed network logs, including SSL handshake events—reused connections won't generate a new handshake log line.
- For Android: Enable debug logging for the system's SSL stack via JNI bridge or a helper class. You can add code to log when handshakes start, then check if the second
- Timing Tests:
- Measure the duration of each request. Reused connections (with KeepAlive) will have much lower latency than the first request (which includes handshake overhead). Compare the time taken for the first and second
siteArequests in Scenario 1—if the second is noticeably faster, connection reuse is working as intended.
- Measure the duration of each request. Reused connections (with KeepAlive) will have much lower latency than the first request (which includes handshake overhead). Compare the time taken for the first and second
内容的提问来源于stack exchange,提问作者zeus

