From 5f5bf97c17659c5b1a87546dd32c693c2aef962a Mon Sep 17 00:00:00 2001 From: skrupin Date: Thu, 27 Oct 2016 15:48:19 +0500 Subject: [PATCH] fix buffering in web socket with using single mWritePendings bufferList (creating for every web socket instance) --- .../koushikdutta/async/BufferedDataSink.java | 8 +++++++- .../koushikdutta/async/FilteredDataSink.java | 7 ++++++- .../koushikdutta/async/http/WebSocketImpl.java | 7 +++++-- .../async/http/filter/ChunkedOutputFilter.java | 5 +++++ .../http/server/AsyncHttpServerResponse.java | 3 +++ .../server/AsyncHttpServerResponseImpl.java | 17 ++++++++++------- 6 files changed, 36 insertions(+), 11 deletions(-) diff --git a/AndroidAsync/src/com/koushikdutta/async/BufferedDataSink.java b/AndroidAsync/src/com/koushikdutta/async/BufferedDataSink.java index d7b16f53e..e7e891161 100644 --- a/AndroidAsync/src/com/koushikdutta/async/BufferedDataSink.java +++ b/AndroidAsync/src/com/koushikdutta/async/BufferedDataSink.java @@ -8,9 +8,15 @@ public class BufferedDataSink implements DataSink { DataSink mDataSink; public BufferedDataSink(DataSink datasink) { + mPendingWrites = new ByteBufferList(); setDataSink(datasink); } + public BufferedDataSink(AsyncSocket mSocket, ByteBufferList byteBufferList) { + mPendingWrites = byteBufferList; + setDataSink(mSocket); + } + public boolean isBuffering() { return mPendingWrites.hasRemaining() || forceBuffering; } @@ -52,7 +58,7 @@ private void writePending() { mWritable.onWriteable(); } - ByteBufferList mPendingWrites = new ByteBufferList(); + ByteBufferList mPendingWrites; @Override public void write(ByteBufferList bb) { diff --git a/AndroidAsync/src/com/koushikdutta/async/FilteredDataSink.java b/AndroidAsync/src/com/koushikdutta/async/FilteredDataSink.java index 8aa1806c2..1f5f777be 100644 --- a/AndroidAsync/src/com/koushikdutta/async/FilteredDataSink.java +++ b/AndroidAsync/src/com/koushikdutta/async/FilteredDataSink.java @@ -5,7 +5,12 @@ public FilteredDataSink(DataSink sink) { super(sink); setMaxBuffer(0); } - + + public FilteredDataSink(AsyncSocket mSocket, ByteBufferList mWritePendings) { + super(mSocket, mWritePendings); + setMaxBuffer(0); + } + public ByteBufferList filter(ByteBufferList bb) { return bb; } diff --git a/AndroidAsync/src/com/koushikdutta/async/http/WebSocketImpl.java b/AndroidAsync/src/com/koushikdutta/async/http/WebSocketImpl.java index ab1404d87..dbd19fdb6 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/WebSocketImpl.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/WebSocketImpl.java @@ -21,6 +21,9 @@ import java.util.UUID; public class WebSocketImpl implements WebSocket { + + private final ByteBufferList mWritePendings = new ByteBufferList(); + @Override public void end() { mSocket.end(); @@ -136,7 +139,7 @@ public WebSocketImpl(AsyncHttpServerRequest request, AsyncHttpServerResponse res response.getHeaders().set("Sec-WebSocket-Protocol", protocol); // if (origin != null) // response.getHeaders().getHeaders().set("Access-Control-Allow-Origin", "http://" + origin); - response.writeHead(); + response.writeHead(mWritePendings); setupParser(false, false); } @@ -159,7 +162,7 @@ public static void addWebSocketUpgradeHeaders(AsyncHttpRequest req, String proto public WebSocketImpl(AsyncSocket socket) { mSocket = socket; - mSink = new BufferedDataSink(mSocket); + mSink = new BufferedDataSink(mSocket, mWritePendings); } public static WebSocket finishHandshake(Headers requestHeaders, AsyncHttpResponse response) { diff --git a/AndroidAsync/src/com/koushikdutta/async/http/filter/ChunkedOutputFilter.java b/AndroidAsync/src/com/koushikdutta/async/http/filter/ChunkedOutputFilter.java index 00d3f9e31..ffa32bf96 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/filter/ChunkedOutputFilter.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/filter/ChunkedOutputFilter.java @@ -2,6 +2,7 @@ import java.nio.ByteBuffer; +import com.koushikdutta.async.AsyncSocket; import com.koushikdutta.async.ByteBufferList; import com.koushikdutta.async.DataSink; import com.koushikdutta.async.FilteredDataSink; @@ -11,6 +12,10 @@ public ChunkedOutputFilter(DataSink sink) { super(sink); } + public ChunkedOutputFilter(AsyncSocket mSocket, ByteBufferList mWritePenings) { + super(mSocket, mWritePenings); + } + @Override public ByteBufferList filter(ByteBufferList bb) { String chunkLen = Integer.toString(bb.remaining(), 16) + "\r\n"; diff --git a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerResponse.java b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerResponse.java index f66c7a29d..86b446271 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerResponse.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerResponse.java @@ -1,6 +1,7 @@ package com.koushikdutta.async.http.server; import com.koushikdutta.async.AsyncSocket; +import com.koushikdutta.async.ByteBufferList; import com.koushikdutta.async.DataSink; import com.koushikdutta.async.callback.CompletedCallback; import com.koushikdutta.async.http.AsyncHttpResponse; @@ -34,4 +35,6 @@ public interface AsyncHttpServerResponse extends DataSink, CompletedCallback { */ public void onCompleted(Exception ex); public AsyncSocket getSocket(); + + void writeHead(ByteBufferList mWritePendings); } diff --git a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerResponseImpl.java b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerResponseImpl.java index 61a8aa347..53b474f9a 100644 --- a/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerResponseImpl.java +++ b/AndroidAsync/src/com/koushikdutta/async/http/server/AsyncHttpServerResponseImpl.java @@ -2,11 +2,7 @@ import android.text.TextUtils; -import com.koushikdutta.async.AsyncServer; -import com.koushikdutta.async.AsyncSocket; -import com.koushikdutta.async.ByteBufferList; -import com.koushikdutta.async.DataSink; -import com.koushikdutta.async.Util; +import com.koushikdutta.async.*; import com.koushikdutta.async.callback.CompletedCallback; import com.koushikdutta.async.callback.DataCallback; import com.koushikdutta.async.callback.WritableCallback; @@ -31,6 +27,7 @@ public class AsyncHttpServerResponseImpl implements AsyncHttpServerResponse { private Headers mRawHeaders = new Headers(); private long mContentLength = -1; + private ByteBufferList mWritePendings; @Override public Headers getHeaders() { @@ -108,12 +105,12 @@ public void onCompleted(Exception ex) { return; } if (isChunked) { - ChunkedOutputFilter chunked = new ChunkedOutputFilter(mSocket); + ChunkedOutputFilter chunked = new ChunkedOutputFilter(mSocket, mWritePendings); chunked.setMaxBuffer(0); mSink = chunked; } else { - mSink = mSocket; + mSink = new BufferedDataSink(mSocket, mWritePendings); } mSink.setClosedCallback(closedCallback); @@ -192,6 +189,12 @@ public void writeHead() { initFirstWrite(); } + @Override + public void writeHead(ByteBufferList mWritePendings) { + this.mWritePendings = mWritePendings; + writeHead(); + } + @Override public void setContentType(String contentType) { mRawHeaders.set("Content-Type", contentType);