Author: markt
Date: Mon Feb 20 20:32:34 2012
New Revision: 1291432
URL: http://svn.apache.org/viewvc?rev=1291432&view=rev
Log:
Improve handling of larger messages
Modified:
tomcat/trunk/java/org/apache/catalina/websocket/MessageInbound.java
tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java
Modified: tomcat/trunk/java/org/apache/catalina/websocket/MessageInbound.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/MessageInbound.java?rev=1291432&r1=1291431&r2=1291432&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/websocket/MessageInbound.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/websocket/MessageInbound.java Mon Feb
20 20:32:34 2012
@@ -24,8 +24,10 @@ import java.nio.CharBuffer;
public abstract class MessageInbound extends StreamInbound {
- // TODO: Make buffer sizes configurable
- // TODO: Allow buffers to expand
+ // 2MB - like maxPostSize
+ private int byteBufferMaxSize = 2097152;
+ private int charBufferMaxSize = 2097152;
+
ByteBuffer bb = ByteBuffer.allocate(8192);
CharBuffer cb = CharBuffer.allocate(8192);
@@ -34,6 +36,9 @@ public abstract class MessageInbound ext
int read = 0;
while (read > -1) {
bb.position(bb.position() + read);
+ if (bb.remaining() == 0) {
+ resizeByteBuffer();
+ }
read = is.read(bb.array(), bb.position(), bb.remaining());
}
bb.flip();
@@ -46,6 +51,9 @@ public abstract class MessageInbound ext
int read = 0;
while (read > -1) {
cb.position(cb.position() + read);
+ if (cb.remaining() == 0) {
+ resizeCharBuffer();
+ }
read = r.read(cb.array(), cb.position(), cb.remaining());
}
cb.limit(cb.position());
@@ -54,6 +62,60 @@ public abstract class MessageInbound ext
cb.clear();
}
+ private void resizeByteBuffer() throws IOException {
+ int maxSize = getByteBufferMaxSize();
+ if (bb.limit() >= maxSize) {
+ // TODO i18n
+ throw new IOException("Buffer not big enough for message");
+ }
+
+ long newSize = bb.limit() * 2;
+ if (newSize > maxSize) {
+ newSize = maxSize;
+ }
+
+ // Cast is safe. newSize < maxSize and maxSize is an int
+ ByteBuffer newBuffer = ByteBuffer.allocate((int) newSize);
+ bb.rewind();
+ newBuffer.put(bb);
+ bb = newBuffer;
+ }
+
+ private void resizeCharBuffer() throws IOException {
+ int maxSize = getCharBufferMaxSize();
+ if (cb.limit() >= maxSize) {
+ // TODO i18n
+ throw new IOException("Buffer not big enough for message");
+ }
+
+ long newSize = cb.limit() * 2;
+ if (newSize > maxSize) {
+ newSize = maxSize;
+ }
+
+ // Cast is safe. newSize < maxSize and maxSize is an int
+ CharBuffer newBuffer = CharBuffer.allocate((int) newSize);
+ cb.rewind();
+ newBuffer.put(cb);
+ cb = newBuffer;
+ }
+
+ public int getByteBufferMaxSize() {
+ return byteBufferMaxSize;
+ }
+
+ public void setByteBufferMaxSize(int byteBufferMaxSize) {
+ this.byteBufferMaxSize = byteBufferMaxSize;
+ }
+
+ public int getCharBufferMaxSize() {
+ return charBufferMaxSize;
+ }
+
+ public void setCharBufferMaxSize(int charBufferMaxSize) {
+ this.charBufferMaxSize = charBufferMaxSize;
+ }
+
protected abstract void onBinaryMessage(ByteBuffer message)
throws IOException;
protected abstract void onTextMessage(CharBuffer message)
Modified: tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java?rev=1291432&r1=1291431&r2=1291432&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java (original)
+++ tomcat/trunk/java/org/apache/catalina/websocket/WsOutbound.java Mon Feb 20
20:32:34 2012
@@ -25,7 +25,7 @@ import org.apache.tomcat.util.buf.B2CCon
public class WsOutbound {
- private static final int DEFAULT_BUFFER_SIZE = 2048;
+ private static final int DEFAULT_BUFFER_SIZE = 8192;
private UpgradeOutbound upgradeOutbound;
private ByteBuffer bb;
@@ -37,9 +37,7 @@ public class WsOutbound {
public WsOutbound(UpgradeOutbound upgradeOutbound) {
this.upgradeOutbound = upgradeOutbound;
// TODO: Make buffer size configurable
- // Byte buffer needs to be 4* char buffer to be sure that char buffer
- // can always we written into Byte buffer
- this.bb = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE * 4);
+ this.bb = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
this.cb = CharBuffer.allocate(DEFAULT_BUFFER_SIZE);
}
@@ -170,8 +168,16 @@ public class WsOutbound {
protected void doWriteText(CharBuffer buffer, boolean finalFragment)
throws IOException {
buffer.flip();
- B2CConverter.UTF_8.newEncoder().encode(buffer, bb, true);
- doWriteBinary(bb, finalFragment);
+
+ do {
+ B2CConverter.UTF_8.newEncoder().encode(buffer, bb, true);
+ if (buffer.hasRemaining()) {
+ doWriteBinary(bb, false);
+ } else {
+ doWriteBinary(bb, finalFragment);
+ }
+ } while (buffer.hasRemaining());
+
// Reset
cb.clear();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]