我正在使用 java.net.http.HttpClient 发送一些请求并忽略响应,但是当我尝试测试时,我注意到如果我不稍等一下,请求就不会发送。
我有一个非常简单的方法:
public CompletableFuture<HttpResponse<String>> getAsyncHttp(final String url) {
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.build();
System.out.println("Send request : " + url);
return httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString());
}
我这样称呼:
private static void callRequest(){
HttpAsyncRequest httpAsyncRequest = new HttpAsyncRequest();
String URL = "http://localhost:3000/test";
httpAsyncRequest.getAsyncHttp(URL);
System.out.println("Request done.");
// we exit here basically
}
我只是尝试发送http请求并故意忽略响应,但请求并未发送。
但是,如果更改我的 callRequest() 方法并添加线程睡眠
private static void callRequest() throws InterruptedException {
HttpAsyncRequest httpAsyncRequest = new HttpAsyncRequest();
String URL = "http://localhost:3000/test";
httpAsyncRequest.getAsyncHttp(URL);
Thread.sleep(100); // line added
System.out.println("Request done.");
// we exit here basically
}
现在请求已发送,但当我不等待服务器时,非常需要添加线程睡眠,因为我只是发送请求。
人们可以重现此问题或愿意解释为什么会发生吗?
谢谢你。
调用是异步的。这意味着它独立于其调用线程执行。除非您收到已完成的通知,否则您不知道它已“完成”。
获取通知正是“sendAsync”调用返回 Future 的原因。在 callRequest 方法中等待 Future(例如,通过“get”),不要忽略它。
我读到您不需要响应,但是您选择使用的 API 无法知道请求甚至已经离开本地系统,更不用说到达远程服务器了。如果没有某种响应,您就无法知道服务器是否以及何时看到该请求;这是不可知的。 (在 TCP 级别,ack 仅意味着它已到达远程 TCP 堆栈)。因此,等待响应是使其可靠的唯一方法。