2017-11-24 9 views
0

私はUndertowで真の非同期のhttpサーバを構築する方法を理解しようとします。どのリクエストを既に処理している別のスレッドがある場合、非同期的にレスポンスを送信するのですか?
は、私はこのようなコードを書いた:データなしとし、ログにUndertown。他のスレッドとの非同期応答

Undertow server = Undertow.builder() 
      .addHttpListener(8080, "localhost") 
      .setHandler(exchange -> { 
       CompletableFuture.runAsync(() -> { 
        try { 
         Thread.sleep(100); 
        } catch (InterruptedException e) { 
         throw new RuntimeException(e); 
        } 
       }).thenAccept(string -> { 
        exchange.getResponseHeaders() 
          .put(Headers.CONTENT_TYPE, "text/plain"); 
        exchange.getResponseSender().send("Hello World"); 
        exchange.endExchange(); 
       }).exceptionally(throwable -> { 
        System.out.println(throwable.toString()); 
        return null; 
       }); 
      }).build(); 
    server.start(); 

が、このサーバーの応答200を

java.lang.IllegalStateException:UT000127:レスポンスがすでに送信されてい

io.undertow.server.HttpServerExchange#dispatch(java.lang.Runnable)メソッドを次のように使用すると:

Undertow server = Undertow.builder() 
      .addHttpListener(8080, "localhost") 
      .setHandler(exchange -> { 

       exchange.dispatch(() -> { 

        CompletableFuture.runAsync(() -> { 
         try { 
          Thread.sleep(100); 
         } catch (InterruptedException e) { 
          throw new RuntimeException(e); 
         } 
        }).thenAccept(string -> { 
         exchange.getResponseHeaders() 
           .put(Headers.CONTENT_TYPE,"text/plain"); 
         exchange.getResponseSender().send("Hello World"); 
         exchange.endExchange(); 
        }).exceptionally(throwable -> { 
         System.out.println(throwable.toString()); 
         return null; 
        }); 

       }); 
      }).build(); 
    server.start(); 

もちろん "Hello World"は期待通りですが、サーバーはリクエストごとに新しいスレッドを作成します!

(10の並列要求の後jvisualvm) jvisualvm after 10 parallel requests

+0

P.S.を私は主な方法でそれを実行します。 – QIvan

答えて

0

暗流この方法をサポートしていない、

私はそれを解決するために、新しいプロジェクトを作成します:

https://github.com/hank-whu/undertow-async

package io.undertow.async.pingpong; 

import java.io.IOException; 
import java.util.concurrent.CompletableFuture; 

import io.undertow.async.handler.AsyncHttpHandler; 
import io.undertow.async.io.PooledByteBufferInputStream; 
import io.undertow.async.io.PooledByteBufferOutputStream; 
import io.undertow.connector.ByteBufferPool; 
import io.undertow.server.HttpServerExchange; 
import io.undertow.util.StatusCodes; 

public class PingPongAsyncHttpHandler extends AsyncHttpHandler { 

    @Override 
    protected void handleAsyncRequest(HttpServerExchange exchange, PooledByteBufferInputStream content) 
      throws Exception { 

     CompletableFuture// 
       .completedFuture(content)// init 
       .thenApplyAsync(this::readBytesAndClose)// read 
       .thenApplyAsync(bytes -> {// write 
        ByteBufferPool byteBufferPool = exchange.getConnection().getByteBufferPool(); 
        PooledByteBufferOutputStream output = new PooledByteBufferOutputStream(byteBufferPool); 
        write(output, bytes); 
        return output; 
       })// 
       .thenAcceptAsync(output -> send(exchange, StatusCodes.OK, output)); 
    } 

    private byte[] readBytesAndClose(PooledByteBufferInputStream content) { 
     try { 
      byte[] bytes = new byte[content.available()]; 
      content.read(bytes); 
      return bytes; 
     } catch (IOException e) { 
      throw new RuntimeException(e); 
     } finally { 
      try {// must close it 
       content.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    private void write(PooledByteBufferOutputStream output, byte[] bytes) { 
     try { 
      output.write("asycn response: "); 
      output.write(bytes); 
     } catch (IOException e) { 
      throw new RuntimeException(e); 
     } 
    } 

} 
関連する問題