Author: markt Date: Thu Mar 15 23:53:01 2012 New Revision: 1301280 URL: http://svn.apache.org/viewvc?rev=1301280&view=rev Log: Implement chat example Plus some minor clean-up. Patch provided by Johno Crawford
Added: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/chat/ tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/chat/ChatWebSocketServlet.java (with props) tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/echo/ tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/echo/EchoMessage.java - copied, changed from r1300930, tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/EchoMessage.java tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/echo/EchoStream.java - copied, changed from r1300930, tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/EchoStream.java Removed: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/EchoMessage.java tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/EchoStream.java Modified: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/SnakeWebSocketServlet.java tomcat/trunk/webapps/examples/WEB-INF/web.xml tomcat/trunk/webapps/examples/websocket/echo.html tomcat/trunk/webapps/examples/websocket/index.html tomcat/trunk/webapps/examples/websocket/snake.html Added: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/chat/ChatWebSocketServlet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/chat/ChatWebSocketServlet.java?rev=1301280&view=auto ============================================================================== --- tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/chat/ChatWebSocketServlet.java (added) +++ tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/chat/ChatWebSocketServlet.java Thu Mar 15 23:53:01 2012 @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package websocket.chat; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.catalina.websocket.MessageInbound; +import org.apache.catalina.websocket.StreamInbound; +import org.apache.catalina.websocket.WebSocketServlet; +import org.apache.catalina.websocket.WsOutbound; + +import util.HTMLFilter; + +/** + * Example web socket servlet for chat. + */ +public class ChatWebSocketServlet extends WebSocketServlet { + + private static final long serialVersionUID = 1L; + + private static final String GUEST_PREFIX = "Guest"; + + private final AtomicInteger connectionIds = new AtomicInteger(0); + private final Set<ChatMessageInbound> connections = + new CopyOnWriteArraySet<ChatMessageInbound>(); + + @Override + protected StreamInbound createWebSocketInbound(String subProtocol) { + return new ChatMessageInbound(connectionIds.incrementAndGet()); + } + + private final class ChatMessageInbound extends MessageInbound { + + private final String nickname; + + private ChatMessageInbound(int id) { + this.nickname = GUEST_PREFIX + id; + } + + @Override + protected void onOpen(WsOutbound outbound) { + connections.add(this); + String message = String.format("* %s %s", + nickname, "has joined."); + broadcast(message); + } + + @Override + protected void onClose(int status) { + connections.remove(this); + String message = String.format("* %s %s", + nickname, "has disconnected."); + broadcast(message); + } + + @Override + protected void onBinaryMessage(ByteBuffer message) throws IOException { + throw new UnsupportedOperationException( + "Binary message not supported."); + } + + @Override + protected void onTextMessage(CharBuffer message) throws IOException { + // Never trust the client + String filteredMessage = String.format("%s: %s", + nickname, HTMLFilter.filter(message.toString())); + broadcast(filteredMessage); + } + + private void broadcast(String message) { + for (ChatMessageInbound connection : connections) { + try { + CharBuffer buffer = CharBuffer.wrap(message); + connection.getWsOutbound().writeTextMessage(buffer); + } catch (IOException ignore) { + // Ignore + } + } + } + } +} \ No newline at end of file Propchange: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/chat/ChatWebSocketServlet.java ------------------------------------------------------------------------------ svn:eol-style = native Copied: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/echo/EchoMessage.java (from r1300930, tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/EchoMessage.java) URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/echo/EchoMessage.java?p2=tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/echo/EchoMessage.java&p1=tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/EchoMessage.java&r1=1300930&r2=1301280&rev=1301280&view=diff ============================================================================== --- tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/EchoMessage.java (original) +++ tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/echo/EchoMessage.java Thu Mar 15 23:53:01 2012 @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package websocket; +package websocket.echo; import java.io.IOException; import java.nio.ByteBuffer; Copied: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/echo/EchoStream.java (from r1300930, tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/EchoStream.java) URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/echo/EchoStream.java?p2=tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/echo/EchoStream.java&p1=tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/EchoStream.java&r1=1300930&r2=1301280&rev=1301280&view=diff ============================================================================== --- tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/EchoStream.java (original) +++ tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/echo/EchoStream.java Thu Mar 15 23:53:01 2012 @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package websocket; +package websocket.echo; import java.io.IOException; import java.io.InputStream; Modified: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java?rev=1301280&r1=1301279&r2=1301280&view=diff ============================================================================== --- tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java (original) +++ tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/Snake.java Thu Mar 15 23:53:01 2012 @@ -93,8 +93,14 @@ public class Snake { head = nextLocation; } + handleCollisions(snakes); + } + + private void handleCollisions(Collection<Snake> snakes) { for (Snake snake : snakes) { - if (snake.getTail().contains(head)) { + boolean headCollision = id != snake.id && snake.getHead().equals(head); + boolean tailCollision = snake.getTail().contains(head); + if (headCollision || tailCollision) { kill(); if (id != snake.id) { snake.reward(); @@ -103,6 +109,10 @@ public class Snake { } } + public synchronized Location getHead() { + return head; + } + public synchronized Collection<Location> getTail() { return tail; } Modified: tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/SnakeWebSocketServlet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/SnakeWebSocketServlet.java?rev=1301280&r1=1301279&r2=1301280&view=diff ============================================================================== --- tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/SnakeWebSocketServlet.java (original) +++ tomcat/trunk/webapps/examples/WEB-INF/classes/websocket/snake/SnakeWebSocketServlet.java Thu Mar 15 23:53:01 2012 @@ -98,8 +98,8 @@ public class SnakeWebSocketServlet exten private void broadcast(String message) { for (SnakeMessageInbound connection : getConnections()) { try { - CharBuffer response = CharBuffer.wrap(message); - connection.getWsOutbound().writeTextMessage(response); + CharBuffer buffer = CharBuffer.wrap(message); + connection.getWsOutbound().writeTextMessage(buffer); } catch (IOException ignore) { // Ignore } Modified: tomcat/trunk/webapps/examples/WEB-INF/web.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/web.xml?rev=1301280&r1=1301279&r2=1301280&view=diff ============================================================================== --- tomcat/trunk/webapps/examples/WEB-INF/web.xml (original) +++ tomcat/trunk/webapps/examples/WEB-INF/web.xml Thu Mar 15 23:53:01 2012 @@ -350,7 +350,7 @@ <!-- WebSocket Examples --> <servlet> <servlet-name>wsEchoStream</servlet-name> - <servlet-class>websocket.EchoStream</servlet-class> + <servlet-class>websocket.echo.EchoStream</servlet-class> </servlet> <servlet-mapping> <servlet-name>wsEchoStream</servlet-name> @@ -358,7 +358,7 @@ </servlet-mapping> <servlet> <servlet-name>wsEchoMessage</servlet-name> - <servlet-class>websocket.EchoMessage</servlet-class> + <servlet-class>websocket.echo.EchoMessage</servlet-class> <!-- Uncomment the following block to increase the default maximum WebSocket buffer size from 2MB to 20MB which is required for the Autobahn test suite to pass fully. --> @@ -378,6 +378,14 @@ <url-pattern>/websocket/echoMessage</url-pattern> </servlet-mapping> <servlet> + <servlet-name>wsChat</servlet-name> + <servlet-class>websocket.chat.ChatWebSocketServlet</servlet-class> + </servlet> + <servlet-mapping> + <servlet-name>wsChat</servlet-name> + <url-pattern>/websocket/chat</url-pattern> + </servlet-mapping> + <servlet> <servlet-name>wsSnake</servlet-name> <servlet-class>websocket.snake.SnakeWebSocketServlet</servlet-class> </servlet> Modified: tomcat/trunk/webapps/examples/websocket/echo.html URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/websocket/echo.html?rev=1301280&r1=1301279&r2=1301280&view=diff ============================================================================== --- tomcat/trunk/webapps/examples/websocket/echo.html (original) +++ tomcat/trunk/webapps/examples/websocket/echo.html Thu Mar 15 23:53:01 2012 @@ -30,7 +30,7 @@ #console-container { float: left; - padding-left: 20px; + margin-left: 15px; width: 400px; } @@ -121,8 +121,8 @@ </script> </head> <body> -<noscript><h1>Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable - Javascript and reload this page!</h1></noscript> +<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable + Javascript and reload this page!</h2></noscript> <div> <div id="connect-container"> <div> Modified: tomcat/trunk/webapps/examples/websocket/index.html URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/websocket/index.html?rev=1301280&r1=1301279&r2=1301280&view=diff ============================================================================== --- tomcat/trunk/webapps/examples/websocket/index.html (original) +++ tomcat/trunk/webapps/examples/websocket/index.html Thu Mar 15 23:53:01 2012 @@ -15,15 +15,17 @@ limitations under the License. --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<HTML><HEAD><TITLE>Apache Tomcat WebSocket Examples</TITLE> -<META http-equiv=Content-Type content="text/html"> -</HEAD> -<BODY> -<P> -<H3>Apache Tomcat WebSocket Examples</H3> -<P></P> +<html> +<head> + <meta http-equiv=Content-Type content="text/html"> + <title>Apache Tomcat WebSocket Examples</title> +</head> +<body> +<h3>Apache Tomcat WebSocket Examples</h3> <ul> -<li><a href="echo.html">Echo example</a></li> -<li><a href="snake.html">Multiplayer snake example</a></li> + <li><a href="echo.html">Echo example</a></li> + <li><a href="chat.html">Chat example</a></li> + <li><a href="snake.html">Multiplayer snake example</a></li> </ul> -</BODY></HTML> \ No newline at end of file +</body> +</html> \ No newline at end of file Modified: tomcat/trunk/webapps/examples/websocket/snake.html URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/websocket/snake.html?rev=1301280&r1=1301279&r2=1301280&view=diff ============================================================================== --- tomcat/trunk/webapps/examples/websocket/snake.html (original) +++ tomcat/trunk/webapps/examples/websocket/snake.html Thu Mar 15 23:53:01 2012 @@ -51,8 +51,8 @@ </style> </head> <body> - <noscript><h1>Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable - Javascript and reload this page!</h1></noscript> + <noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable + Javascript and reload this page!</h2></noscript> <div style="float: left"> <canvas id="playground" width="640" height="480"></canvas> </div> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org