2017-04-07 108 views
0

我已經在Java中建立了一個HttpsServer。我所有的溝通都很完美。我設置了多個上下文,加載自簽名證書,甚至基於外部配置文件啓動。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()和其他幾個。但是,他們都產生了相同的結果。每個人都以不同的方式管理線程,但第一個請求必須在第二個請求處理之前完成。

我也試着寫我自己的遺囑執行人

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通過執行Thread.sleep(10000)命中模擬長時間運行任務的/ Test端點。在運行時,我正在使用我的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(); 
     } 
    } 
} 
+0

你可能需要添加一些源代碼展示瞭如何在安裝了港口裝卸和實際處理個別請求在你的http服務器中:對於我們所知道的,你一次只能接受一個套接字。 – Femi

+0

我怎麼能改變HttpsServer接受多個套接字? – cain4355

+0

它已經做到了。你如何處理接受的套接字? – EJP

回答

0

嘗試指定一個非零的最大積壓(第二個參數create()):

HttpsServer server = HttpsServer.create(new InetSocketAddress(secureConnection.getPort()), 10); 
+0

我也玩過這個。這涉及與服務器相關的積壓。我甚至爲這個領域測試了高達1000。我仍然得到相同的結果。 – cain4355