Author: markt Date: Wed Apr 24 19:55:57 2013 New Revision: 1471619 URL: http://svn.apache.org/r1471619 Log: Outbound errors need to trigger an onClose event on the inbound side
Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/StreamInbound.java tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/WsOutbound.java tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/StreamInbound.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/StreamInbound.java?rev=1471619&r1=1471618&r2=1471619&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/StreamInbound.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/StreamInbound.java Wed Apr 24 19:55:57 2013 @@ -88,7 +88,7 @@ public abstract class StreamInbound impl @Override public final void setUpgradeOutbound(UpgradeOutbound upgradeOutbound) { - outbound = new WsOutbound(upgradeOutbound, outboundByteBufferSize, + outbound = new WsOutbound(upgradeOutbound, this, outboundByteBufferSize, outboundCharBufferSize); } @@ -207,7 +207,13 @@ public abstract class StreamInbound impl } } - private void doOnClose(int status) { + /** + * Package private so the outbound connection can signal that the connection + * has been closed - usually due to an error. + * + * @param status The WebSocket status code to report to the application + */ + void doOnClose(int status) { // Need to call onClose using the web application's class loader Thread t = Thread.currentThread(); ClassLoader cl = t.getContextClassLoader(); Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/WsOutbound.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/WsOutbound.java?rev=1471619&r1=1471618&r2=1471619&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/WsOutbound.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/WsOutbound.java Wed Apr 24 19:55:57 2013 @@ -39,6 +39,7 @@ public class WsOutbound { public static final int DEFAULT_BUFFER_SIZE = 8192; private UpgradeOutbound upgradeOutbound; + private StreamInbound streamInbound; private ByteBuffer bb; private CharBuffer cb; private boolean closed = false; @@ -46,14 +47,17 @@ public class WsOutbound { private boolean firstFrame = true; - public WsOutbound(UpgradeOutbound upgradeOutbound) { - this(upgradeOutbound, DEFAULT_BUFFER_SIZE, DEFAULT_BUFFER_SIZE); + public WsOutbound(UpgradeOutbound upgradeOutbound, + StreamInbound streamInbound) { + this(upgradeOutbound, streamInbound, DEFAULT_BUFFER_SIZE, + DEFAULT_BUFFER_SIZE); } - public WsOutbound(UpgradeOutbound upgradeOutbound, int byteBufferSize, - int charBufferSize) { + public WsOutbound(UpgradeOutbound upgradeOutbound, StreamInbound streamInbound, + int byteBufferSize, int charBufferSize) { this.upgradeOutbound = upgradeOutbound; + this.streamInbound = streamInbound; this.bb = ByteBuffer.allocate(byteBufferSize); this.cb = CharBuffer.allocate(charBufferSize); } @@ -365,54 +369,60 @@ public class WsOutbound { throw new IOException(sm.getString("outbound.closed")); } - // Work out the first byte - int first = 0x00; - if (finalFragment) { - first = first + 0x80; - } - if (firstFrame) { - if (text.booleanValue()) { - first = first + 0x1; + try { + // Work out the first byte + int first = 0x00; + if (finalFragment) { + first = first + 0x80; + } + if (firstFrame) { + if (text.booleanValue()) { + first = first + 0x1; + } else { + first = first + 0x2; + } + } + // Continuation frame is OpCode 0 + upgradeOutbound.write(first); + + if (buffer.limit() < 126) { + upgradeOutbound.write(buffer.limit()); + } else if (buffer.limit() < 65536) { + upgradeOutbound.write(126); + upgradeOutbound.write(buffer.limit() >>> 8); + upgradeOutbound.write(buffer.limit() & 0xFF); } else { - first = first + 0x2; + // Will never be more than 2^31-1 + upgradeOutbound.write(127); + upgradeOutbound.write(0); + upgradeOutbound.write(0); + upgradeOutbound.write(0); + upgradeOutbound.write(0); + upgradeOutbound.write(buffer.limit() >>> 24); + upgradeOutbound.write(buffer.limit() >>> 16); + upgradeOutbound.write(buffer.limit() >>> 8); + upgradeOutbound.write(buffer.limit() & 0xFF); } + + // Write the content + upgradeOutbound.write(buffer.array(), buffer.arrayOffset(), + buffer.limit()); + upgradeOutbound.flush(); + + // Reset + if (finalFragment) { + text = null; + firstFrame = true; + } else { + firstFrame = false; + } + bb.clear(); + } catch (IOException ioe) { + // Any IOException is terminal. Make sure the Inbound side knows + // that something went wrong. + streamInbound.doOnClose(Constants.STATUS_CLOSED_UNEXPECTEDLY); + throw ioe; } - // Continuation frame is OpCode 0 - upgradeOutbound.write(first); - - if (buffer.limit() < 126) { - upgradeOutbound.write(buffer.limit()); - } else if (buffer.limit() < 65536) { - upgradeOutbound.write(126); - upgradeOutbound.write(buffer.limit() >>> 8); - upgradeOutbound.write(buffer.limit() & 0xFF); - } else { - // Will never be more than 2^31-1 - upgradeOutbound.write(127); - upgradeOutbound.write(0); - upgradeOutbound.write(0); - upgradeOutbound.write(0); - upgradeOutbound.write(0); - upgradeOutbound.write(buffer.limit() >>> 24); - upgradeOutbound.write(buffer.limit() >>> 16); - upgradeOutbound.write(buffer.limit() >>> 8); - upgradeOutbound.write(buffer.limit() & 0xFF); - - } - - // Write the content - upgradeOutbound.write(buffer.array(), buffer.arrayOffset(), - buffer.limit()); - upgradeOutbound.flush(); - - // Reset - if (finalFragment) { - text = null; - firstFrame = true; - } else { - firstFrame = false; - } - bb.clear(); } Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1471619&r1=1471618&r2=1471619&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Wed Apr 24 19:55:57 2013 @@ -72,6 +72,12 @@ any web-fragment.xml should not impact the status of distributable element. Patch provided by Trask Stalnaker. (violetagg) </fix> + <fix> + When an error occurs during the sending of a WebSocket message, notify + the Inbound side (where all the events occur that the application reacts + to) that an error has occurred and that the connection is being closed. + (markt) + </fix> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org