HI I m trying to write a client that makes http2 request to multiple
servers(which already supports http2). so far I have written this
standalone program which works fine that I can see all requests goes via
same tcp connection(verified with the help of wireshark). I use Apache
Httpclient 5 with conscrypt to support ALPN in jdk8 (jdk8 is my
requirement, I cannot upgrade to jdk9 or later)
The Main block goes like,
try {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager(){
public X509Certificate[] getAcceptedIssuers(){ return null; }
public void checkClientTrusted(X509Certificate[] certs,
String authType) {}
public void checkServerTrusted(X509Certificate[] certs,
String authType) {}
}
};
Provider provider = Conscrypt.newProvider();
SSLContext sslContext = SSLContext.getInstance("TLSv1.3", provider);
sslContext.init(null, trustAllCerts, new SecureRandom());
client = Http2AsyncClientBuilder.create().setTlsStrategy(new
ConscryptClientTlsStrategy(sslContext)).setH2Config(H2Config.DEFAULT).build();
client.start();
ThreadPoolExecutor tpe =
(ThreadPoolExecutor)Executors.newFixedThreadPool(50);
for (int i=0; i < 50; i++) {
Runnable worker = new WorkerClass(client, i);
tpe.execute(worker);
}} catch (Exception e) {
e.printStackTrace();}
The runnable goes like,
static class WorkerClass implements Runnable {
CloseableHttpAsyncClient client = null;
int i = 0;
WorkerClass(CloseableHttpAsyncClient client, int i) {
this.client = client;
this.i = i;
}
public void run() {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(Timeout.of(15,
TimeUnit.SECONDS))//Determines the timeout until a new connection is
fully established.
.setConnectionRequestTimeout(Timeout.of(60,
TimeUnit.SECONDS))//Returns the connection lease request timeout used
when requesting a connection from the connection manager.
.setResponseTimeout(Timeout.of(60,
TimeUnit.SECONDS))//Determines the timeout until arrival of a response
from the opposite endpoint.
.build();
String url =
"https://localhost:8081/myagent/getOutput?"+System.currentTimeMillis();
String cachedXMLRequest = "<?xml version=\"1.0\"
standalone=\"no\"?><My XML REQUEST GOES HERE>";
SimpleHttpRequest request= SimpleHttpRequests.POST.create(url);
request.setBodyText(cachedXMLRequest, ContentType.APPLICATION_JSON);
request.setConfig(requestConfig);
final CountDownLatch latch = new CountDownLatch(1);
client.execute(request, new FutureCallback<SimpleHttpResponse>() {
@Override
public void cancelled() {
System.out.println("Cancelled");
latch.countDown();
}
@Override
public void completed(SimpleHttpResponse arg0) {
System.out.println("Completed "+arg0.getBodyText());
latch.countDown();
}
@Override
public void failed(Exception exception) {
System.out.println("Failed ");
exception.printStackTrace();
latch.countDown();
}
});
try {
latch.await(60, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}
So I simulated this standalone in my client which asynchronously calls
multiple servers for polling using the above logic. But here I can see one
tcp connection per request and the connection is closed at the end of the
request(Though the response header returns as HTTP/2.0). I use the main
block code to initialize the client at the startup of my application and
create the url, request and response objects and execute each request
simultaneously in a threaded model(Asynchronous multiplexing). My
requirement is to use one tcp connection per domain and use it for
prolonged time for handling high number of requests. What am I missing here?
Or someone hep me with the proper way fo handling http2 using httpclient 5
Kindy shed some light on it.
SO link :
https://stackoverflow.com/questions/54548110/how-to-do-http2-correctly-with-apache-httpcient-5-beta
TIA
--
*With Regards,*
*Santhosh Kumar J*