From b4fbb77321683adab30526aab622be884f2925ef Mon Sep 17 00:00:00 2001
From: Paul-Christian Volkmer <paul-christian.volkmer@mni.thm.de>
Date: Sun, 29 Jul 2012 17:40:06 +0200
Subject: [PATCH] Add servlet class for simple websocket handling

This websocket servlet class simply holds a list of connections and
broadcasts all incomming data to every connected client.
---
 .../de/thm/arsnova/websockets/Message.java    | 98 +++++++++++++++++++
 src/main/webapp/WEB-INF/web.xml               | 26 +++++
 2 files changed, 124 insertions(+)
 create mode 100644 src/main/java/de/thm/arsnova/websockets/Message.java

diff --git a/src/main/java/de/thm/arsnova/websockets/Message.java b/src/main/java/de/thm/arsnova/websockets/Message.java
new file mode 100644
index 000000000..f4f2575e2
--- /dev/null
+++ b/src/main/java/de/thm/arsnova/websockets/Message.java
@@ -0,0 +1,98 @@
+package de.thm.arsnova.websockets;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.catalina.websocket.MessageInbound;
+import org.apache.catalina.websocket.StreamInbound;
+import org.apache.catalina.websocket.WebSocketServlet;
+import org.apache.catalina.websocket.WsOutbound;
+
+public class Message extends WebSocketServlet {
+
+	private static final long serialVersionUID = 1L;
+	private volatile int byteBufSize;
+	private volatile int charBufSize;
+
+	@Override
+	public void init() throws ServletException {
+		System.out.println("init();");
+		super.init();
+		byteBufSize = getInitParameterIntValue("byteBufferMaxSize", 2097152);
+		charBufSize = getInitParameterIntValue("charBufferMaxSize", 2097152);
+	}
+
+	public int getInitParameterIntValue(String name, int defaultValue) {
+		String val = this.getInitParameter(name);
+		int result;
+		if (null != val) {
+			try {
+				result = Integer.parseInt(val);
+			} catch (Exception x) {
+				result = defaultValue;
+			}
+		} else {
+			result = defaultValue;
+		}
+
+		return result;
+	}
+
+	@Override
+	protected StreamInbound createWebSocketInbound(String subProtocol,
+			HttpServletRequest request) {
+		// TODO Auto-generated method stub
+		return new MessageInboundImpl(byteBufSize, charBufSize);
+	}
+
+	private final static List<MessageInbound> connections = new ArrayList<MessageInbound>();
+	
+	private static final class MessageInboundImpl extends MessageInbound {
+
+		public MessageInboundImpl(int byteBufferMaxSize, int charBufferMaxSize) {
+			super();
+			setByteBufferMaxSize(byteBufferMaxSize);
+			setCharBufferMaxSize(charBufferMaxSize);
+		}
+
+		@Override
+		protected void onOpen(WsOutbound outbound) {
+			connections.add(this);
+			super.onOpen(outbound);
+		}
+		
+		@Override
+		protected void onClose(int status) {
+			connections.remove(this);
+			super.onClose(status);
+		}
+		
+		@Override
+		protected void onBinaryMessage(ByteBuffer message) throws IOException {
+			throw new UnsupportedOperationException("Binary message not supported.");
+		}
+
+		@Override
+		protected void onTextMessage(CharBuffer message) throws IOException {
+			//getWsOutbound().writeTextMessage(message);
+			broadcast(message.toString());
+		}
+
+		private void broadcast(String message) {
+			for (MessageInbound connection : connections) {
+				try {
+					CharBuffer buffer = CharBuffer.wrap(message);
+					connection.getWsOutbound().writeTextMessage(buffer);
+				} catch (IOException ignore) {
+					// Ignore
+				}
+			}
+		}
+	}
+}
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
index e2a153cff..93b2d0e4e 100644
--- a/src/main/webapp/WEB-INF/web.xml
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -16,6 +16,32 @@
 	<listener>
 		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 	</listener>
+	<servlet>
+        <servlet-name>
+			wsMessage
+        </servlet-name>
+        <servlet-class>
+			de.thm.arsnova.websockets.Message
+        </servlet-class>
+        <!--
+	      <init-param>
+	        <param-name>byteBufferMaxSize</param-name>
+	        <param-value>20971520</param-value>
+	      </init-param>
+	      <init-param>
+	        <param-name>charBufferMaxSize</param-name>
+	        <param-value>20971520</param-value>
+	      </init-param>
+        -->
+    </servlet>
+    <servlet-mapping>
+	    <servlet-name>
+			wsMessage
+        </servlet-name>
+        <url-pattern>
+			/websocket/message
+        </url-pattern>
+    </servlet-mapping>
 	<servlet>
 		<servlet-name>arsnova</servlet-name>
 		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
-- 
GitLab