1

Tomcat 6 で comet を使用して、データをクライアントにプッシュします。

接続が閉じる前にデータを受信したい (XMLHttpRequest の準備状態 = 3)。問題は、Tomcat 6 がデータを送信する前にバッファリングするため、これを行うにはトリッキーなことをする必要があることです。

request コンテンツ タイプを application/x-javascript に設定し、req コンテンツ タイプを application/xml に設定しました (ブラウザのキャッシュを無効にするため)。

私は tomcat 6 で利用可能な多くのオプションを使用してキャッシュを無効にしました (socketBuffer = -1 in nio コネクタなど...)。これはローカルの tomcat 6 (Windows OS 上) で機能します (実際には、デフォルト オプションを変更しなくても) )。

しかし、Tomcat 6 と同じ構成の場合、 http://jelastic.comが提供する Tomcat 6 サーバーにアプリケーションをデプロイすると、サーバーの出力バッファーが大きくなり、出力ライターのフラッシュをトリガーするために空のバイトを送信する必要があります。 (次のコードを参照)

byte[] bytes = new byte[event.getHttpServletResponse().getBufferSize()-new Gson().toJson(messagesContent).getBytes().length]; event.getHttpServletResponse().getOutputStream().write(new Gson().toJson(messagesContent).getBytes()); event.getHttpServletResponse().getOutputStream().write(bytes); event.getHttpServletResponse().getOutputStream().flush();

データ コンテンツに加えてバイトを書き込まないと、データはクライアントに送信されません。無駄な空のバイトを送信し、クライアントでこれらの空のバイトを管理する必要があるため、これは本当に面倒です。最悪。

誰かが解決策を持っていますか? comet サーブレットの出力バッファーを無効にする方法。デフォルトで comet サーブレットの出力バッファを無効にする必要があることは明らかです。奇妙に聞こえます。

よろしくお願いします。

J

4

1 に答える 1

3

フィルタを使用してみましたか? http://www.oracle.com/technetwork/java/filters-137243.htmlカスタマイズされた要求と応答のプログラミング

デコレータパターンを使用すると、出力を制御できます。これを行う方法は、応答を生成するサーブレットをスタンドインストリームに渡すことです。代用ストリームは、サーブレットが完了したときに元の応答ストリームを閉じるのを防ぎます。

class CharResponseWrapper extends HttpServletResponseWrapper {
    private CharArrayWriter output;
    public String toString() {
      return output.toString();
    }
    public ResponseWrapper(HttpServletResponse response) {
        super(response); 
        output = new CharArrayWriter();
    }
    public PrintWriter getWriter(){
        return new PrintWriter(output);
    }

}

したがって、フィルターのdoFilterメソッドで、元のPrintWritterを取得し、ラッパーを渡します

PrintWriter out = response.getWriter();
CharResponseWrapper wrapper = new CharResponseWrapper((HttpServletResponse)response);
chain.doFilter(request, wrapper);

そして、サーブレットはCharrArrayWritterのすべての出力を書き込むので、バッファリングせずに文字列で出力を取得できます。

wrapper.toString()

次に、変更、追加などを行ってから、元の応答出力を使用してコンテンツを書き込むことができます。

out.write(wrapper.toString());
out.close();
于 2012-11-09T13:44:55.573 に答える