【发布时间】:2017-09-02 07:26:56
【问题描述】:
我已经用 Java 设置了一个 HttpsServer。我所有的沟通都完美无缺。我设置了多个上下文,加载自签名证书,甚至基于外部配置文件启动。
我现在的问题是让多个客户端能够访问我的安全服务器。为此,我想以某种方式对来自 HttpsServer 的请求进行多线程处理,但不知道该怎么做。下面是我的基本 HttpsConfiguration。
HttpsServer server = HttpsServer.create(new InetSocketAddress(secureConnection.getPort()), 0);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(secureConnection.getKeyManager().getKeyManagers(), secureConnection.getTrustManager().getTrustManagers(), null);
server.setHttpsConfigurator(new SecureServerConfiguration(sslContext));
server.createContext("/", new RootHandler());
server.createContext("/test", new TestHandler());
server.setExecutor(Executors.newCachedThreadPool());
server.start();
其中secureConnection 是一个包含服务器设置和证书信息的自定义类。
我试图将执行程序设置为Executors.newCachedThreadPool() 和其他几个。但是,它们都产生了相同的结果。每个都以不同的方式管理线程,但第一个请求必须在第二个请求处理之前完成。
我也尝试编写自己的 Executor
public class AsyncExecutor extends ThreadPoolExecutor implements Executor
{
public static Executor create()
{
return new AsyncExecutor();
}
public AsyncExecutor()
{
super(5, 10, 10000, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(12));
}
@Override
public void execute(Runnable process)
{
System.out.println("New Process");
Thread newProcess = new Thread(process);
newProcess.setDaemon(false);
newProcess.start();
System.out.println("Thread created");
}
}
不幸的是,结果与其他执行者相同。
为了进行测试,我使用 Postman 来访问 /Test 端点,该端点通过执行 Thread.sleep(10000) 来模拟长时间运行的任务。当它运行时,我正在使用我的 Chrome 浏览器来访问根端点。直到 10 秒睡眠结束后,才会加载根页面。
关于如何处理对 HTTPS 服务器的多个并发请求有什么想法吗?
为了便于测试,我使用标准 HttpServer 复制了我的场景,并将所有内容压缩到一个 java 程序中。
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class Example
{
private final static int PORT = 80;
private final static int BACKLOG = 10;
/**
* To test hit:
* <p><b>http://localhost/test</b></p>
* <p>This will hit the endoint with the thread sleep<br>
* Then hit:</p>
* <p><b>http://localhost</b></p>
* <p>I would expect this to come back right away. However, it does not come back until the
* first request finishes. This can be tested with only a basic browser.</p>
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception
{
new Example().start();
}
private void start() throws Exception
{
HttpServer server = HttpServer.create(new InetSocketAddress(PORT), BACKLOG);
server.createContext("/", new RootHandler());
server.createContext("/test", new TestHandler());
server.setExecutor(Executors.newCachedThreadPool());
server.start();
System.out.println("Server Started on " + PORT);
}
class RootHandler implements HttpHandler
{
@Override
public void handle(HttpExchange httpExchange) throws IOException
{
String body = "<html>Hello World</html>";
httpExchange.sendResponseHeaders(200, body.length());
OutputStream outputStream = httpExchange.getResponseBody();
outputStream.write(body.getBytes("UTF-8"));
outputStream.close();
}
}
class TestHandler implements HttpHandler
{
@Override
public void handle(HttpExchange httpExchange) throws IOException
{
try
{
Thread.sleep(10000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
String body = "<html>Test Handled</html>";
httpExchange.sendResponseHeaders(200, body.length());
OutputStream outputStream = httpExchange.getResponseBody();
outputStream.write(body.getBytes("UTF-8"));
outputStream.close();
}
}
}
【问题讨论】:
-
您可能需要添加一些源代码来展示如何设置端口处理并实际处理 http 服务器中的各个请求:据我们所知,您一次只接受一个套接字。跨度>
-
如何更改 HttpsServer 以接受多个套接字?
-
它已经做到了。您如何处理接受的套接字?
-
我自己没有对套接字进行任何操作。我以为 HttpsServer 已经为我处理好了。
-
我仍然无法解决这个问题。有没有人有其他想法?
标签: java multithreading http https threadpoolexecutor