gpt4 book ai didi

java - 服务请求后停止 HttpServer

转载 作者:可可西里 更新时间:2023-11-01 16:32:46 25 4
gpt4 key购买 nike

我正在使用来自 com.sun.net.httpserver 的简单 Http 服务器,如 simple HTTP server in Java using only Java SE API 中所述.

一切正常,但我不确定一旦我不再需要它时如何彻底关闭服务器。我不想在服务器仍在为某些请求发送数据时停止服务器,只有在它空闲时才停止。

我的特定场景是执行 OAuth 舞蹈的桌面应用程序。我使用应用程序中嵌入的本地 Web 服务器提供回调响应,应用程序启动桌面浏览器以使用 java.awt.Desktop.browse 显示服务器响应应用程序接口(interface)。

我试过调用HttpServer.stop(0)直接来 self 的 HttpHandler.handle函数,在我将响应页面写入 HttpExchange 之后响应输出流,但这还为时过早,浏览器显示 ERR_EMPTY_RESPONSE .

当我在主应用程序完成其工作后停止服务器时,也会发生同样的情况 - 这通常为时过早,HttpServer此时尚未完成数据发送。

我可以提供几秒的延迟值来停止,但我想实现正确且干净的同步。

什么是正确的解决方案?

最佳答案

我可以提供一个基于一个 CountDownLatch + 自定义 ExecutorService 的解决方案,它被设置为 HttpServer 的执行程序:

public void runServer() throws Exception {
final ExecutorService ex = Executors.newSingleThreadExecutor();
final CountDownLatch c = new CountDownLatch(1);

HttpServer server = HttpServer.create(new InetSocketAddress(8888), 0);

server.createContext("/test", (HttpExchange h) -> {
StringBuilder resp = new StringBuilder();
for (int i = 0; i < 1_000_000; i++)
resp.append(i).append(", ");
String response = resp.toString();
h.sendResponseHeaders(200, response.length());
OutputStream os = h.getResponseBody();
os.write(response.getBytes());
os.close();
c.countDown(); // count down, letting `c.await()` to return
});

server.setExecutor(ex); // set up a custom executor for the server
server.start(); // start the server
System.out.println("HTTP server started");
c.await(); // wait until `c.countDown()` is invoked
ex.shutdown(); // send shutdown command to executor
// wait until all tasks complete (i. e. all responses are sent)
ex.awaitTermination(1, TimeUnit.HOURS);
server.stop(0);
System.out.println("HTTP server stopped");
}

我确实在我们的工作网络环境中对此进行了测试,它似乎可以正常工作。 HttpServer 在响应完全发送之前停止,所以我认为这正是您所需要的。

另一种方法可能不是关闭执行器 ex,而是在将响应写入流后向那里发送一个包含 server.stop() 的新任务。由于 ex 是单线程构造的,因此此类任务的执行时间不会早于前一个任务完成,即。 e.响应已完全发送:

public void run() throws Exception {
final ExecutorService ex = Executors.newSingleThreadExecutor();
final HttpServer server = HttpServer.create(new InetSocketAddress(8888), 0);

server.createContext("/test", (HttpExchange h) -> {
// ... generate and write a response
ex.submit(() -> {
server.stop(0);
System.out.println("HTTP server stopped");
});
});
server.setExecutor(ex);
server.start();
System.out.println("HTTP server started");
}

有关详细信息,请参阅 ExecutorService

关于java - 服务请求后停止 HttpServer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36127945/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com