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: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org