Author: markt Date: Fri Mar 2 19:07:01 2012 New Revision: 1296388 URL: http://svn.apache.org/viewvc?rev=1296388&view=rev Log: Implement notification of open and close for WebSocket connections. Patch provided by Johno Crawford.
Modified: tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeInbound.java Modified: tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java?rev=1296388&r1=1296387&r2=1296388&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java (original) +++ tomcat/trunk/java/org/apache/catalina/websocket/StreamInbound.java Fri Mar 2 19:07:01 2012 @@ -20,6 +20,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.nio.ByteBuffer; import java.nio.charset.MalformedInputException; import java.nio.charset.UnmappableCharacterException; @@ -113,7 +114,7 @@ public abstract class StreamInbound impl try { // TODO User defined extensions may define values for rsv if (frame.getRsv() > 0) { - getWsOutbound().close( + closeOutboundConnection( Constants.STATUS_PROTOCOL_ERROR, null); return SocketState.CLOSED; } @@ -127,7 +128,7 @@ public abstract class StreamInbound impl new InputStreamReader(wsIs, new Utf8Decoder()); onTextData(r); } else if (opCode == Constants.OPCODE_CLOSE){ - getWsOutbound().close(frame); + closeOutboundConnection(frame); return SocketState.CLOSED; } else if (opCode == Constants.OPCODE_PING) { getWsOutbound().pong(frame.getPayLoad()); @@ -135,22 +136,22 @@ public abstract class StreamInbound impl // NO-OP } else { // Unknown OpCode - getWsOutbound().close( + closeOutboundConnection( Constants.STATUS_PROTOCOL_ERROR, null); return SocketState.CLOSED; } } catch (MalformedInputException mie) { // Invalid UTF-8 - getWsOutbound().close(Constants.STATUS_BAD_DATA, null); + closeOutboundConnection(Constants.STATUS_BAD_DATA, null); return SocketState.CLOSED; } catch (UnmappableCharacterException uce) { // Invalid UTF-8 - getWsOutbound().close(Constants.STATUS_BAD_DATA, null); + closeOutboundConnection(Constants.STATUS_BAD_DATA, null); return SocketState.CLOSED; } catch (IOException ioe) { // Given something must have gone to reach this point, this // might not work but try it anyway. - getWsOutbound().close(Constants.STATUS_PROTOCOL_ERROR, null); + closeOutboundConnection(Constants.STATUS_PROTOCOL_ERROR, null); return SocketState.CLOSED; } frame = wsIs.nextFrame(false); @@ -158,6 +159,49 @@ public abstract class StreamInbound impl return SocketState.UPGRADED; } + private void closeOutboundConnection(int status, ByteBuffer data) throws IOException { + try { + getWsOutbound().close(status, data); + } finally { + onClose(status); + } + } + + private void closeOutboundConnection(WsFrame frame) throws IOException { + try { + getWsOutbound().close(frame); + } finally { + onClose(Constants.OPCODE_CLOSE); + } + } + + @Override + public void onUpgradeComplete() { + onOpen(outbound); + } + + /** + * Intended to be overridden by sub-classes that wish to be notified + * when the outbound connection is established. The default implementation + * is a NO-OP. + * + * @param outbound The outbound WebSocket connection. + */ + protected void onOpen(WsOutbound outbound) { + // NO-OP + } + + /** + * Intended to be overridden by sub-classes that wish to be notified + * when the outbound connection is closed. The default implementation + * is a NO-OP. + * + * @param status The status code of the close reason. + */ + protected void onClose(int status) { + // NO-OP + } + /** * This method is called when there is a binary WebSocket message available Modified: tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java?rev=1296388&r1=1296387&r2=1296388&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/AbstractProtocol.java Fri Mar 2 19:07:01 2012 @@ -571,6 +571,7 @@ public abstract class AbstractProtocol i release(socket, processor, false, false); // Create the light-weight upgrade processor processor = createUpgradeProcessor(socket, inbound); + inbound.onUpgradeComplete(); } } while (state == SocketState.ASYNC_END || state == SocketState.UPGRADING); Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeInbound.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeInbound.java?rev=1296388&r1=1296387&r2=1296388&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeInbound.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeInbound.java Fri Mar 2 19:07:01 2012 @@ -28,6 +28,8 @@ public interface UpgradeInbound { void setUpgradeProcessor(UpgradeProcessor<?> processor); + void onUpgradeComplete(); + SocketState onData() throws IOException; void setUpgradeOutbound(UpgradeOutbound upgradeOutbound); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org