Author: markt Date: Thu Mar 15 22:40:37 2012 New Revision: 1301253 URL: http://svn.apache.org/viewvc?rev=1301253&view=rev Log: Start to merge WebSocket implementation from trunk. I'm combining commits where I can but I can't back-port in a single commit as they interleave with other commits.
Added: tomcat/tc7.0.x/trunk/java/org/apache/catalina/util/Conversions.java - copied unchanged from r1239047, tomcat/trunk/java/org/apache/catalina/util/Conversions.java tomcat/tc7.0.x/trunk/java/org/apache/catalina/websocket/ - copied from r1239047, tomcat/trunk/java/org/apache/catalina/websocket/ tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/UpgradeInbound.java - copied unchanged from r1239047, tomcat/trunk/java/org/apache/coyote/http11/UpgradeInbound.java tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/UpgradeInputStream.java - copied unchanged from r1239047, tomcat/trunk/java/org/apache/coyote/http11/UpgradeInputStream.java tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/UpgradeOutbound.java - copied unchanged from r1239047, tomcat/trunk/java/org/apache/coyote/http11/UpgradeOutbound.java tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/UpgradeOutputStream.java - copied unchanged from r1239047, tomcat/trunk/java/org/apache/coyote/http11/UpgradeOutputStream.java tomcat/tc7.0.x/trunk/test/org/apache/catalina/websocket/ - copied from r1239047, tomcat/trunk/test/org/apache/catalina/websocket/ tomcat/tc7.0.x/trunk/webapps/examples/WEB-INF/classes/websocket/ - copied from r1239047, tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/ tomcat/tc7.0.x/trunk/webapps/examples/websocket/ - copied from r1239047, tomcat/trunk/webapps/examples/websocket/ Modified: tomcat/tc7.0.x/trunk/ (props changed) tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/Request.java tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/RequestFacade.java tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProcessor.java tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProtocol.java tomcat/tc7.0.x/trunk/java/org/apache/coyote/ActionCode.java tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/LocalStrings.properties tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/AbstractInputBuffer.java tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/InternalAprInputBuffer.java tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java tomcat/tc7.0.x/trunk/webapps/examples/WEB-INF/web.xml tomcat/tc7.0.x/trunk/webapps/examples/index.html Propchange: tomcat/tc7.0.x/trunk/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Thu Mar 15 22:40:37 2012 @@ -1 +1 @@ -/tomcat/trunk:1156115-1157160,1157162-1157859,1157862-1157942,1157945-1160347,1160349-1163716,1163718-1166689,1166691-1174340,1174342-1175596,1175598-1175611,1175613-1175932,1175934-1177783,1177785-1177980,1178006-1180720,1180722-1183094,1183096-1187753,1187755,1187775,1187801,1187806,1187809,1187826-1188312,1188314-1188401,1188646-1188840,1188842-1190176,1190178-1195223,1195225-1195953,1195955,1195957-1201238,1201240-1203345,1203347-1206623,1206625-1208046,1208073,1208096,1208114,1208145,1208772,1209194-1212125,1212127-1220291,1220293,1220295-1221321,1221323-1222328,1222332-1222401,1222405-1222795,1222850-1222950,1222969-1225326,1225328-1225463,1225465,1225627,1225629-1226534,1226536-1228908,1228911-1228923,1228927-1229532,1229534-1230766,1230768-1231625,1231627-1233414,1233419-1235207,1235209-1237425,1237427,1237429-1237977,1237981,1237985,1238070,1238073,1239024,1239048,1239050,1239060,1239135,1239483,1239485,1240101,1240106,1240109,1240112,1240114,1240116,1240118,1240121 ,1240329,1240697,1240795,1240821,1240842,1240857,1241087,1241160,1241908-1241909,1241982,1242099,1242110,1242371,1242434,1242495,1242947,1243034,1243038,1244302,1244511,1244567,1244718-1244719,1244935-1244938,1245274,1245449,1245849,1290875,1292334,1292338,1292345-1292347,1293155,1293831-1293832,1295998,1296284,1297014-1297015,1297017,1297158,1297177,1297202,1297209,1297213,1297717,1297722,1297729,1297768,1297778,1297818,1297828,1297979,1297987,1298121,1298140,1298590,1298592,1298628-1298629,1298794,1298983-1298984,1299020,1299034,1299819,1300154-1300155,1300569,1300948 +/tomcat/trunk:1156115-1157160,1157162-1157859,1157862-1157942,1157945-1160347,1160349-1163716,1163718-1166689,1166691-1174340,1174342-1175596,1175598-1175611,1175613-1175932,1175934-1177783,1177785-1177980,1178006-1180720,1180722-1183094,1183096-1187753,1187755,1187775,1187801,1187806,1187809,1187826-1188312,1188314-1188401,1188646-1188840,1188842-1190176,1190178-1195223,1195225-1195953,1195955,1195957-1201238,1201240-1203345,1203347-1206623,1206625-1208046,1208073,1208096,1208114,1208145,1208772,1209194-1212125,1212127-1220291,1220293,1220295-1221321,1221323-1222328,1222332-1222401,1222405-1222795,1222850-1222950,1222969-1225326,1225328-1225463,1225465,1225627,1225629-1226534,1226536-1228908,1228911-1228923,1228927-1229532,1229534-1230766,1230768-1231625,1231627-1233414,1233419-1235207,1235209-1237425,1237427,1237429-1237977,1237981,1237985,1238070,1238073,1239024-1239048,1239050-1239062,1239135,1239483,1239485,1240101,1240106,1240109,1240112,1240114,1240116,1240118,1240121 ,1240329,1240697,1240795,1240821,1240842,1240857,1241087,1241160,1241908-1241909,1241982,1242099,1242110,1242371,1242434,1242495,1242947,1243034,1243038,1244302,1244511,1244567,1244718-1244719,1244935-1244938,1245274,1245449,1245849,1290875,1292334,1292338,1292345-1292347,1293155,1293831-1293832,1295998,1296284,1297014-1297015,1297017,1297158,1297177,1297202,1297209,1297213,1297717,1297722,1297729,1297768,1297778,1297818,1297828,1297979,1297987,1298121,1298140,1298590,1298592,1298628-1298629,1298794,1298983-1298984,1299020,1299034,1299819,1300154-1300155,1300569,1300948 Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/Request.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/Request.java?rev=1301253&r1=1301252&r2=1301253&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/Request.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/Request.java Thu Mar 15 22:40:37 2012 @@ -74,6 +74,7 @@ import org.apache.catalina.realm.Generic import org.apache.catalina.util.ParameterMap; import org.apache.catalina.util.StringParser; import org.apache.coyote.ActionCode; +import org.apache.coyote.http11.UpgradeInbound; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.ExceptionUtils; @@ -2802,6 +2803,21 @@ public class Request return null; } + + // --------------------------------------------------------- Upgrade Methods + + public void doUpgrade(UpgradeInbound inbound) + throws IOException { + + coyoteRequest.action(ActionCode.UPGRADE, inbound); + + // Output required by RFC2616. Protocol specific headers should have + // already been set. + response.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS); + response.flushBuffer(); + } + + // ------------------------------------------------------ Protected Methods Modified: tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/RequestFacade.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/RequestFacade.java?rev=1301253&r1=1301252&r2=1301253&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/RequestFacade.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/connector/RequestFacade.java Thu Mar 15 22:40:37 2012 @@ -41,6 +41,7 @@ import javax.servlet.http.Part; import org.apache.catalina.Globals; import org.apache.catalina.security.SecurityUtil; +import org.apache.coyote.http11.UpgradeInbound; import org.apache.tomcat.util.res.StringManager; /** @@ -1085,4 +1086,20 @@ public class RequestFacade implements Ht return request.getConnector().getAllowTrace(); } + /** + * Sets the response status to {@link + * HttpServletResponse.SC_SWITCHING_PROTOCOLS} and flushes the response. + * Protocol specific headers must have already been set before this method + * is called. + * + * @param inbound The handler for all further incoming data on the current + * connection. + * + * @throws IOException If the upgrade fails (e.g. if the response has + * already been committed. + */ + public void doUpgrade(UpgradeInbound inbound) + throws IOException { + request.doUpgrade(inbound); + } } Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProcessor.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProcessor.java?rev=1301253&r1=1301252&r2=1301253&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProcessor.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProcessor.java Thu Mar 15 22:40:37 2012 @@ -106,6 +106,8 @@ public abstract class AbstractProcessor< protected abstract boolean isComet(); + protected abstract boolean isUpgrade(); + /** * Process HTTP requests. All requests are treated as HTTP requests to start * with although they may change type during processing. @@ -113,7 +115,6 @@ public abstract class AbstractProcessor< public abstract SocketState process(SocketWrapper<S> socket) throws IOException; - /** * Process in-progress Comet requests. These will start as HTTP requests. */ @@ -124,4 +125,10 @@ public abstract class AbstractProcessor< * requests. */ public abstract SocketState asyncDispatch(SocketStatus status); + + /** + * Processes data received on a connection that has been through an HTTP + * upgrade. + */ + public abstract SocketState upgradeDispatch() throws IOException; } Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProtocol.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProtocol.java?rev=1301253&r1=1301252&r2=1301253&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProtocol.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/AbstractProtocol.java Thu Mar 15 22:40:37 2012 @@ -551,6 +551,8 @@ public abstract class AbstractProtocol i state = processor.asyncDispatch(status); } else if (processor.isComet()) { state = processor.event(status); + } else if (processor.isUpgrade()) { + state = processor.upgradeDispatch(); } else { state = processor.process(socket); } @@ -574,6 +576,9 @@ public abstract class AbstractProtocol i // closed. If it works, the socket will be re-added to the // poller release(socket, processor, false, false); + } else if (state == SocketState.UPGRADE) { + // Need to keep the connection associated with the processor + longPoll(socket, processor); } else { // Connection closed. OK to recycle the processor. release(socket, processor, true, false); Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/ActionCode.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/ActionCode.java?rev=1301253&r1=1301252&r2=1301253&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/coyote/ActionCode.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/ActionCode.java Thu Mar 15 22:40:37 2012 @@ -189,5 +189,10 @@ public enum ActionCode { /** * Callback to determine if async is timing out */ - ASYNC_IS_TIMINGOUT + ASYNC_IS_TIMINGOUT, + + /** + * Callback to trigger the HTTP upgrade process. + */ + UPGRADE } Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java?rev=1301253&r1=1301252&r2=1301253&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java Thu Mar 15 22:40:37 2012 @@ -456,6 +456,9 @@ public abstract class AbstractAjpProcess ((AtomicBoolean) param).set(asyncStateMachine.isAsync()); } else if (actionCode == ActionCode.ASYNC_IS_TIMINGOUT) { ((AtomicBoolean) param).set(asyncStateMachine.isAsyncTimingOut()); + } else if (actionCode == ActionCode.UPGRADE) { + // HTTP connections only. Unsupported for AJP. + // NOOP } else { actionInternal(actionCode, param); } @@ -510,6 +513,15 @@ public abstract class AbstractAjpProcess sm.getString("ajpprocessor.comet.notsupported")); } + + @Override + public SocketState upgradeDispatch() throws IOException { + // Should never reach this code but in case we do... + throw new IOException( + sm.getString("ajpprocessor.httpupgrade.notsupported")); + } + + /** * Recycle the processor, ready for the next request which may be on the * same connection or a different connection. @@ -554,6 +566,13 @@ public abstract class AbstractAjpProcess } + @Override + protected final boolean isUpgrade() { + // AJP does not support HTTP upgrade + return false; + } + + /** * Get more request body data from the web server and store it in the * internal buffer. Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/LocalStrings.properties?rev=1301253&r1=1301252&r2=1301253&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/LocalStrings.properties (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/ajp/LocalStrings.properties Thu Mar 15 22:40:37 2012 @@ -40,6 +40,7 @@ ajpprocessor.request.process=Error proce ajpprocessor.certs.fail=Certificate conversion failed ajpprocessor.socket.info=Exception getting socket information ajpprocessor.comet.notsupported=The Comet protocol is not supported by this connector +ajpprocessor.httpupgrade.notsupported=HTTP upgrades are not supported by this connector ajpmessage.null=Cannot append null value ajpmessage.overflow=Overflow error for buffer adding {0} bytes at position {1} Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java?rev=1301253&r1=1301252&r2=1301253&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java Thu Mar 15 22:40:37 2012 @@ -253,6 +253,13 @@ public abstract class AbstractHttp11Proc protected String server = null; + /** + * Listener to which data available events are passed once the associated + * connection has completed the HTTP upgrade process. + */ + protected UpgradeInbound upgradeInbound = null; + + public AbstractHttp11Processor(AbstractEndpoint endpoint) { super(endpoint); } @@ -830,6 +837,15 @@ public abstract class AbstractHttp11Proc ((AtomicBoolean) param).set(asyncStateMachine.isAsync()); } else if (actionCode == ActionCode.ASYNC_IS_TIMINGOUT) { ((AtomicBoolean) param).set(asyncStateMachine.isAsyncTimingOut()); + } else if (actionCode == ActionCode.UPGRADE) { + upgradeInbound = (UpgradeInbound) param; + upgradeInbound.setInputStream( + new UpgradeInputStream(getInputBuffer())); + upgradeInbound.setUpgradeOutbound( + new UpgradeOutbound( + new UpgradeOutputStream(getOutputBuffer()))); + // Stop further HTTP output + getOutputBuffer().finished = true; } else { actionInternal(actionCode, param); } @@ -905,7 +921,7 @@ public abstract class AbstractHttp11Proc } while (!error && keepAlive && !comet && !isAsync() && - !endpoint.isPaused()) { + upgradeInbound == null && !endpoint.isPaused()) { // Parsing the request header try { @@ -1053,6 +1069,9 @@ public abstract class AbstractHttp11Proc return SocketState.CLOSED; } else if (isAsync() || comet) { return SocketState.LONG; + } else if (isUpgrade()) { + // May be data on the connection to process + return upgradeDispatch(); } else { if (sendfileInProgress) { return SocketState.SENDFILE; @@ -1552,6 +1571,34 @@ public abstract class AbstractHttp11Proc } + @Override + public boolean isUpgrade() { + return upgradeInbound != null; + } + + + + @Override + public SocketState upgradeDispatch() throws IOException { + SocketState result = upgradeInbound.onData(); + AbstractInputBuffer<S> ib = getInputBuffer(); + while (result == SocketState.UPGRADE) { + // Check to see if there is more data to process + if (ib.available() == 0) { + // Read any data that might be available + // Note: This will block for BIO regardless + ib.fill(false); + } + if (ib.available() == 0) { + // Still no data available, exit this loop + break; + } + result = upgradeInbound.onData(); + } + return result; + } + + /** * Provides a mechanism for those connector implementations (currently only * NIO) that need to reset timeouts from Async timeouts to standard HTTP @@ -1609,6 +1656,7 @@ public abstract class AbstractHttp11Proc getInputBuffer().recycle(); getOutputBuffer().recycle(); asyncStateMachine.recycle(); + upgradeInbound = null; remoteAddr = null; remoteHost = null; localAddr = null; Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/AbstractInputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/AbstractInputBuffer.java?rev=1301253&r1=1301252&r2=1301253&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/AbstractInputBuffer.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/AbstractInputBuffer.java Thu Mar 15 22:40:37 2012 @@ -310,8 +310,23 @@ public abstract class AbstractInputBuffe } - // ---------------------------------------------------- InputBuffer Methods + /** + * Available bytes in the buffers (note that due to encoding, this may not + * correspond). + */ + public int available() { + int result = (lastValid - pos); + if ((result == 0) && (lastActiveFilter >= 0)) { + for (int i = 0; (result == 0) && (i <= lastActiveFilter); i++) { + result = activeFilters[i].available(); + } + } + return result; + } + + + // ---------------------------------------------------- InputBuffer Methods /** * Read some bytes. Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/InternalAprInputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/InternalAprInputBuffer.java?rev=1301253&r1=1301252&r2=1301253&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/InternalAprInputBuffer.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/InternalAprInputBuffer.java Thu Mar 15 22:40:37 2012 @@ -518,20 +518,6 @@ public class InternalAprInputBuffer exte } - /** - * Available bytes (note that due to encoding, this may not correspond ) - */ - public int available() { - int result = (lastValid - pos); - if ((result == 0) && (lastActiveFilter >= 0)) { - for (int i = 0; (result == 0) && (i <= lastActiveFilter); i++) { - result = activeFilters[i].available(); - } - } - return result; - } - - // ---------------------------------------------------- InputBuffer Methods Modified: tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java?rev=1301253&r1=1301252&r2=1301253&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/coyote/http11/InternalNioInputBuffer.java Thu Mar 15 22:40:37 2012 @@ -763,20 +763,6 @@ public class InternalNioInputBuffer exte } - /** - * Available bytes (note that due to encoding, this may not correspond ) - */ - public int available() { - int result = (lastValid - pos); - if ((result == 0) && (lastActiveFilter >= 0)) { - for (int i = 0; (result == 0) && (i <= lastActiveFilter); i++) { - result = activeFilters[i].available(); - } - } - return result; - } - - // ------------------------------------------------------ Protected Methods @Override Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=1301253&r1=1301252&r2=1301253&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java Thu Mar 15 22:40:37 2012 @@ -55,7 +55,7 @@ public abstract class AbstractEndpoint { public enum SocketState { // TODO Add a new state to the AsyncStateMachine and remove // ASYNC_END (if possible) - OPEN, CLOSED, LONG, ASYNC_END, SENDFILE + OPEN, CLOSED, LONG, ASYNC_END, SENDFILE, UPGRADE } Modified: tomcat/tc7.0.x/trunk/webapps/examples/WEB-INF/web.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/examples/WEB-INF/web.xml?rev=1301253&r1=1301252&r2=1301253&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/examples/WEB-INF/web.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/examples/WEB-INF/web.xml Thu Mar 15 22:40:37 2012 @@ -347,4 +347,22 @@ <url-pattern>/async/stockticker</url-pattern> </servlet-mapping> + <!-- WebSocket Examples --> + <servlet> + <servlet-name>wsEchoStream</servlet-name> + <servlet-class>websocket.EchoStream</servlet-class> + </servlet> + <servlet-mapping> + <servlet-name>wsEchoStream</servlet-name> + <url-pattern>/websocket/echoStream</url-pattern> + </servlet-mapping> + <servlet> + <servlet-name>wsEchoMessage</servlet-name> + <servlet-class>websocket.EchoMessage</servlet-class> + </servlet> + <servlet-mapping> + <servlet-name>wsEchoMessage</servlet-name> + <url-pattern>/websocket/echoMessage</url-pattern> + </servlet-mapping> + </web-app> Modified: tomcat/tc7.0.x/trunk/webapps/examples/index.html URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/examples/index.html?rev=1301253&r1=1301252&r2=1301253&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/examples/index.html (original) +++ tomcat/tc7.0.x/trunk/webapps/examples/index.html Thu Mar 15 22:40:37 2012 @@ -25,5 +25,6 @@ <ul> <li><a href="servlets">Servlets examples</a></li> <li><a href="jsp">JSP Examples</a></li> +<li><a href="websocket">WebSocket Examples</a></li> </ul> </BODY></HTML> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org