Introduction
This article describe how to use HTML5 WebSocket with Tomcat support.
Result
View demo on line
http://screencast.com/t/qyimehPrY
Program
index.html
Initial WebSocket, a button that will trigger WebSocket and display the returned message within content div.
<html>
<head>
<script type="text/javascript">
var TestWebSocket = {
socket: null,
connect: (function() {
var host = 'ws://' + window.location.host + '/TomcatWebSocketTest/testWebSocketServlet';
if ('WebSocket' in window) {
TestWebSocket.socket = new WebSocket(host);
} else if ('MozWebSocket' in window) {
TestWebSocket.socket = new MozWebSocket(host);
} else {
alert('Error: WebSocket is not supported by this browser.');
return;
}
// process message from server
TestWebSocket.socket.onmessage = function (message) {
document.getElementById('content').innerHTML = message.data;
};
/* optional
// do something while onopen/onclose if needed
TestWebSocket.socket.onopen = function () {
alert('WebSocket opened.');
};
TestWebSocket.socket.onclose = function () {
alert('WebSocket closed.');
};
*/
}),
// send message to server
trigger: (function() {
TestWebSocket.socket.send('trigger');
}),
};
TestWebSocket.connect();
</script>
</head>
<body>
<div id="content"></div>
<button id="btn" onclick="TestWebSocket.trigger();">trigger</button>
</body>
</html>
TestWebSocketServlet.java
Create and hold each WebSocket StreamInbound instance, where StreamInbound instance will handle receive/response message it self.
package test;
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 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;
/**
* Tested with Tomcat 7.0.42
* @author benbai123
*
*/
public class TestWebSocketServlet extends WebSocketServlet {
private static final long serialVersionUID = -7663708549630020769L;
// for message that will be sent to client
private final AtomicInteger _cnt = new AtomicInteger(0);
// hold each connection in this Set
private final Set<TestMessageInbound> connections =
new CopyOnWriteArraySet<TestMessageInbound>();
/**
* For create connection only, each connection will
* handle it self as needed
*/
@Override
protected StreamInbound createWebSocketInbound(String subProtocol,
HttpServletRequest request) {
/* enable this fragment to send message by server directly
*
if (_cnt.getAndIncrement() == 0) {
new Thread(new Runnable(){
public void run () {
try{
while (true) {
send();
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
*/
return new TestMessageInbound();
}
private final class TestMessageInbound extends MessageInbound {
// add self instance into connections Set while opened
@Override
protected void onOpen(WsOutbound outbound) {
connections.add(this);
}
// remove self instance from connections Set whild closed
@Override
protected void onClose(int status) {
connections.remove(this);
}
// ignore binary message since we just want to process text messages
@Override
protected void onBinaryMessage(ByteBuffer message) throws IOException {
throw new UnsupportedOperationException(
"Unsupported: Binary message.");
}
// send a message to each connection in connections Set
// while receive a text message
@Override
protected void onTextMessage(CharBuffer message) throws IOException {
send();
}
}
public void send () {
String msg = "Current count: " + _cnt.getAndIncrement();
for (TestMessageInbound connection : connections) {
try {
connection.getWsOutbound().writeTextMessage(CharBuffer.wrap(msg));
} catch (IOException ignore) {
/* ignore */
}
}
}
}
web.xml
Configure WebSocket.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>TomcatWebSocketTest</display-name>
<servlet>
<servlet-name>testWebSocketServlet</servlet-name>
<servlet-class>test.TestWebSocketServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>testWebSocketServlet</servlet-name>
<url-pattern>/testWebSocketServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Reference
Start point of official tutorial.
http://tomcat.apache.org/tomcat-7.0-doc/web-socket-howto.html
Download
Full project at github
https://github.com/benbai123/JSP_Servlet_Practice/tree/master/Practice/WebServer/WebSocket/TomcatWebSocketTest
Demo Flash
https://github.com/benbai123/JSP_Servlet_Practice/blob/master/demo_src/Server/Tomcat/TomcatWebSocketTest.swf
great
ReplyDelete