2

netty 3.3.1 でカスタム HTTP サーバーを開発しています。

このようなものを実装する必要があります

  1. HTTP サーバーがリクエストを受信
  2. HTTP サーバーはそれを解析し、他のマシンへのクライアントとして HTTP 要求を呼び出します。
  3. (2)で送信したリクエストのレスポンスをHTTPサーバーが待つ
  4. HTTP サーバーは、(3) で受信した内容に基づいて、(1) からのリクエストに対する応答を送信します。

これは、クライアント要求 (2) が同期として動作する必要があることを意味します。

私が書いたものはHttpSnoopClient の例に基づいていますが、動作しません。

java.lang.IllegalStateException: 
await*() in I/O thread causes a dead lock or sudden performance drop. Use addListener() instead or call await*() from a different thread. 

上記の例のコードをリファクタリングしたところ、次のようにはなりません (HttpSnoopClient の 7f 行目から)。

    ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
    future.addListener(new ChannelFutureListener() {
      public void operationComplete(ChannelFuture future) {
        if (!future.isSuccess()) {
          System.err.println("Cannot connect"); 
            future.getCause().printStackTrace();
            bootstrap.releaseExternalResources();
            return;
          }
          System.err.println("Connected");

          Channel channel = future.getChannel();

          // Send the HTTP request.
          channel.write(request);
          channel.close();



          // Wait for the server to close the connection.
          channel.getCloseFuture().addListener(new ChannelFutureListener() {
            public void operationComplete(ChannelFuture future) {
              System.err.println("Disconnected"); 
              bootstrap.releaseExternalResources(); // DOES NOT WORK?
            }
          });   
        }
    });

  } 
}

上記の例のrun()コマンドは、messageReceived私の Herver ハンドラーの関数で呼び出されます。

そのため、非同期になり、await* 関数を避けます。リクエストは適切に呼び出されます。しかし、私にとっては未知の理由で、その行

              bootstrap.releaseExternalResources(); // DOES NOT WORK?

動作しません。現在使用しているスレッドを強制終了できないという例外がスローされます (これは合理的に聞こえますが、別の方法でそれを行う方法についてはまだ回答がありません)。

これが正しいアプローチかどうかもわかりませんか?

netty でのこのようなイベント プログラミング手法のチュートリアルをお勧めできますか? 一般に、指定された順序で呼び出され、互いに待機する必要があるいくつかの非同期リクエストを処理する方法は?

ありがとうございました、

4

1 に答える 1

1

閉じるときにブートストラップを本当に解放したい場合は、次のようにできます。

channel.getCloseFuture().addListener(new ChannelFutureListener() {
    public void operationComplete(ChannelFuture future) {
        System.err.println("Disconnected"); 
        new Thread(new Runnable() {
            public void run() {
                bootstrap.releaseExternalResources();
            }
        }).start();
    }
});   
于 2012-04-08T17:46:54.950 に答える