Author: markt Date: Wed Feb 13 20:02:38 2013 New Revision: 1445893 URL: http://svn.apache.org/r1445893 Log: Implement getOpenSessions
Modified: tomcat/trunk/java/javax/websocket/Session.java tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java tomcat/trunk/java/org/apache/tomcat/websocket/server/ServerContainerImpl.java tomcat/trunk/java/org/apache/tomcat/websocket/server/WsProtocolHandler.java tomcat/trunk/test/org/apache/tomcat/websocket/TestWsSession.java tomcat/trunk/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java Modified: tomcat/trunk/java/javax/websocket/Session.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/javax/websocket/Session.java?rev=1445893&r1=1445892&r2=1445893&view=diff ============================================================================== --- tomcat/trunk/java/javax/websocket/Session.java (original) +++ tomcat/trunk/java/javax/websocket/Session.java Wed Feb 13 20:02:38 2013 @@ -107,5 +107,9 @@ public interface Session extends Closeab Principal getUserPrincipal(); + /** + * Obtain the set of currently open sessions for the local endpoint that + * this session is associated with. + */ Set<Session> getOpenSessions(); } Modified: tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java?rev=1445893&r1=1445892&r2=1445893&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/WsSession.java Wed Feb 13 20:02:38 2013 @@ -51,7 +51,7 @@ public class WsSession implements Sessio private final Endpoint localEndpoint; private final WsRemoteEndpointBase wsRemoteEndpoint; private final ClassLoader applicationClassLoader; - private final WebSocketContainer webSocketContainer; + private final WsWebSocketContainer webSocketContainer; private MessageHandler textMessageHandler = null; private MessageHandler binaryMessageHandler = null; @@ -76,13 +76,13 @@ public class WsSession implements Sessio */ public WsSession(Endpoint localEndpoint, WsRemoteEndpointBase wsRemoteEndpoint, - WebSocketContainer webSocketContainer) { + WsWebSocketContainer wsWebSocketContainer) { this.localEndpoint = localEndpoint; this.wsRemoteEndpoint = wsRemoteEndpoint; - this.webSocketContainer = webSocketContainer; + this.webSocketContainer = wsWebSocketContainer; applicationClassLoader = Thread.currentThread().getContextClassLoader(); wsRemoteEndpoint.setAsyncSendTimeout( - webSocketContainer.getDefaultAsyncSendTimeout()); + wsWebSocketContainer.getDefaultAsyncSendTimeout()); this.maxBinaryMessageBufferSize = webSocketContainer.getDefaultMaxBinaryMessageBufferSize(); this.maxTextMessageBufferSize = @@ -240,8 +240,7 @@ public class WsSession implements Sessio @Override public Set<Session> getOpenSessions() { - // TODO Auto-generated method stub - return null; + return webSocketContainer.getOpenSession(localEndpoint.getClass()); } @@ -286,6 +285,9 @@ public class WsSession implements Sessio // TODO - Ignore? } + webSocketContainer.unregisterSession( + localEndpoint.getClass(), this); + // Fire the onClose event Thread t = Thread.currentThread(); ClassLoader cl = t.getContextClassLoader(); Modified: tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java?rev=1445893&r1=1445892&r2=1445893&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/WsWebSocketContainer.java Wed Feb 13 20:02:38 2013 @@ -25,6 +25,7 @@ import java.nio.channels.AsynchronousSoc import java.nio.charset.Charset; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -53,6 +54,10 @@ public class WsWebSocketContainer implem private static final Charset iso88591 = Charset.forName("ISO-8859-1"); private static final byte[] crlf = new byte[] {13, 10}; + private final Map<Class<?>, Set<WsSession>> endpointSessionMap = + new HashMap<>(); + private final Object endPointSessionMapLock = new Object(); + private long defaultAsyncTimeout = -1; private int maxBinaryMessageBufferSize = Constants.DEFAULT_BUFFER_SIZE; private int maxTextMessageBufferSize = Constants.DEFAULT_BUFFER_SIZE; @@ -147,8 +152,8 @@ public class WsWebSocketContainer implem } WsSession wsSession = new WsSession(endpoint, wsRemoteEndpointClient, this); - endpoint.onOpen(wsSession, clientEndpointConfiguration); + registerSession(clazz, wsSession); // Object creation will trigger input processing @SuppressWarnings("unused") @@ -159,6 +164,37 @@ public class WsWebSocketContainer implem } + protected void registerSession(Class<?> endpoint, WsSession wsSession) { + synchronized (endPointSessionMapLock) { + Set<WsSession> wsSessions = endpointSessionMap.get(endpoint); + if (wsSessions == null) { + wsSessions = new HashSet<>(); + endpointSessionMap.put(endpoint, wsSessions); + } + wsSessions.add(wsSession); + } + } + + + protected void unregisterSession(Class<?> endpoint, WsSession wsSession) { + synchronized (endPointSessionMapLock) { + Set<WsSession> wsSessions = endpointSessionMap.get(endpoint); + if (wsSessions != null) { + wsSessions.remove(wsSession); + if (wsSessions.size() == 0) { + endpointSessionMap.remove(endpoint); + } + } + } + } + + + Set<Session> getOpenSession(Class<?> endpoint) { + HashSet<Session> result = new HashSet<>(); + result.addAll(endpointSessionMap.get(endpoint)); + return result; + } + private Map<String,List<String>> createRequestHeaders(String host, int port) { Modified: tomcat/trunk/java/org/apache/tomcat/websocket/server/ServerContainerImpl.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/ServerContainerImpl.java?rev=1445893&r1=1445892&r2=1445893&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/server/ServerContainerImpl.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/server/ServerContainerImpl.java Wed Feb 13 20:02:38 2013 @@ -31,6 +31,7 @@ import javax.websocket.server.ServerEndp import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.res.StringManager; +import org.apache.tomcat.websocket.WsSession; import org.apache.tomcat.websocket.WsWebSocketContainer; import org.apache.tomcat.websocket.pojo.PojoEndpointConfiguration; import org.apache.tomcat.websocket.pojo.PojoMethodMapping; @@ -245,6 +246,28 @@ public class ServerContainerImpl extends /** + * {@inheritDoc} + * + * Overridden to make them visible to other classes in this package. + */ + @Override + protected void registerSession(Class<?> endpoint, WsSession wsSession) { + super.registerSession(endpoint, wsSession); + } + + + /** + * {@inheritDoc} + * + * Overridden to make them visible to other classes in this package. + */ + @Override + protected void unregisterSession(Class<?> endpoint, WsSession wsSession) { + super.unregisterSession(endpoint, wsSession); + } + + + /** * Converts a path defined for a WebSocket endpoint into a path that can be * used as a servlet mapping. * Modified: tomcat/trunk/java/org/apache/tomcat/websocket/server/WsProtocolHandler.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/websocket/server/WsProtocolHandler.java?rev=1445893&r1=1445892&r2=1445893&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/websocket/server/WsProtocolHandler.java (original) +++ tomcat/trunk/java/org/apache/tomcat/websocket/server/WsProtocolHandler.java Wed Feb 13 20:02:38 2013 @@ -93,6 +93,7 @@ public class WsProtocolHandler implement sos.setWriteListener( new WsWriteListener(this, wsRemoteEndpointServer)); ep.onOpen(wsSession, endpointConfig); + webSocketContainer.registerSession(ep.getClass(), wsSession); } finally { t.setContextClassLoader(cl); } Modified: tomcat/trunk/test/org/apache/tomcat/websocket/TestWsSession.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/websocket/TestWsSession.java?rev=1445893&r1=1445892&r2=1445893&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/tomcat/websocket/TestWsSession.java (original) +++ tomcat/trunk/test/org/apache/tomcat/websocket/TestWsSession.java Wed Feb 13 20:02:38 2013 @@ -132,4 +132,6 @@ public class TestWsSession { // NO-OP } } + + } Modified: tomcat/trunk/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java?rev=1445893&r1=1445892&r2=1445893&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java (original) +++ tomcat/trunk/test/org/apache/tomcat/websocket/TestWsWebSocketContainer.java Wed Feb 13 20:02:38 2013 @@ -19,6 +19,7 @@ package org.apache.tomcat.websocket; import java.net.URI; import java.nio.ByteBuffer; import java.util.List; +import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -538,4 +539,72 @@ public class TestWsWebSocketContainer ex } } } + + + @Test + public void testGetOpenSessions() throws Exception { + Tomcat tomcat = getTomcatInstance(); + // Must have a real docBase - just use temp + Context ctx = + tomcat.addContext("", System.getProperty("java.io.tmpdir")); + ctx.addApplicationListener(TesterEchoServer.Config.class.getName()); + + tomcat.start(); + + WebSocketContainer wsContainer = + ContainerProvider.getWebSocketContainer(); + + Session s1a = connectToEchoServerBasic(wsContainer, EndpointA.class); + Session s2a = connectToEchoServerBasic(wsContainer, EndpointA.class); + Session s3a = connectToEchoServerBasic(wsContainer, EndpointA.class); + + Session s1b = connectToEchoServerBasic(wsContainer, EndpointB.class); + Session s2b = connectToEchoServerBasic(wsContainer, EndpointB.class); + + Set<Session> setA = s3a.getOpenSessions(); + Assert.assertEquals(3, setA.size()); + Assert.assertTrue(setA.remove(s1a)); + Assert.assertTrue(setA.remove(s2a)); + Assert.assertTrue(setA.remove(s3a)); + + s1a.close(); + + setA = s3a.getOpenSessions(); + Assert.assertEquals(2, setA.size()); + Assert.assertFalse(setA.remove(s1a)); + Assert.assertTrue(setA.remove(s2a)); + Assert.assertTrue(setA.remove(s3a)); + + Set<Session> setB = s1b.getOpenSessions(); + Assert.assertEquals(2, setB.size()); + Assert.assertTrue(setB.remove(s1b)); + Assert.assertTrue(setB.remove(s2b)); + } + + + private Session connectToEchoServerBasic(WebSocketContainer wsContainer, + Class<? extends Endpoint> clazz) throws Exception { + return wsContainer.connectToServer(clazz, + new DefaultClientConfiguration(), + new URI("http://localhost:" + getPort() + + TesterEchoServer.Config.PATH_BASIC)); + } + + public static final class EndpointA extends Endpoint { + + @Override + public void onOpen(Session session, EndpointConfiguration config) { + // NO-OP + } + } + + + public static final class EndpointB extends Endpoint { + + @Override + public void onOpen(Session session, EndpointConfiguration config) { + // NO-OP + } + } + } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org