WebSockets API using Apache Tomcat Jump Start PRO

Java EE supports the HTML5 WebSockets API. We can easily get a WebSockets server up and running by developing a servlet that extends WebSocketServlet class.

The following code sample includes two files. The following is the HTML file that includes code in JavaScript for using HTML5 Web Sockets API.

<!DOCTYPE html>
<html>
	<head>
	    <title>Simple WebSockets Chat</title>
	    <style type="text/css">
	        input#user-message {
	            width: 360px
	        }	
	        #chat-messages {
	            width: 355px;
	            border: 1px solid #BBBBBB;
	            height: 200px;
	            overflow-y: scroll;
	            padding: 4px;
	        }
	    </style>
	</head>
	<body>
	<div>
	    <input type="text" placeholder="enter your message here" id="user-message">  
	    <div id="chat-messages"></div>
	</div>	
	<script type="text/javascript">
		var chat = {};    
		chat.socket = null;	
	    chat.connect = (function(host) {
	            if ('WebSocket' in window) {
	            	chat.socket = new WebSocket(host);
	            } else if ('MozWebSocket' in window) {
	            	chat.socket = new MozWebSocket(host);
	            } else {
	                return;
	            }	
	            chat.socket.onopen = function () {
	                document.getElementById('user-message').onkeydown = function(event) {
	                    if (event.keyCode == 13) {
	                    	chat.sendMessage();
	                    }
	                };
	            };	
	            chat.socket.onclose = function () {
	                document.getElementById('user-message').onkeydown = null;
	            };	
	            chat.socket.onmessage = function (message) {
	                messages.add(message.data);
	            };
	        });	
	        chat.initialize = function() {
	            if (window.location.protocol == 'http:') {
	            	chat.connect('ws://' + window.location.host + '/websocketproj/WebSocket');
	            } else {
	            	chat.connect('wss://' + window.location.host + '/websocketproj/WebSocket');
	            }
	        };	
	        chat.sendMessage = (function() {
	            var message = document.getElementById('user-message').value;
	            if (message != '') {
	            	chat.socket.send(message);
	                document.getElementById('user-message').value = '';
	            }
	        });     
	   var messages = {};		        
	   messages.add = (function(message) {
	        var ob = document.getElementById('chat-messages');
	        var div = document.createElement('div');
	        div.style.wordWrap = 'break-word';
	        div.innerHTML = message;
	        ob.appendChild(div);
	        while (ob.childNodes.length > 10) {
	        	ob.removeChild(ob.firstChild);
	        }
	   });	
	   chat.initialize();	
	</script>
	</body>
</html>

The following is the source code of a simple Java EE servlet that extends the WebSocketsServlet class and implements the simple code required for getting a WebSockets based working chat.

package com.lifemichael.samples;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.annotation.WebServlet;
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;

@WebServlet("/WebSocket")
public class WebSocket extends WebSocketServlet {

	private static final long serialVersionUID = 1L;

	private final AtomicInteger idGenerator = new AtomicInteger(0);
	private final Set<ChatUser> connections = new HashSet<ChatUser>();

	@Override
	protected StreamInbound createWebSocketInbound(String subProtocol,
			HttpServletRequest request) {
		return new ChatUser(idGenerator.incrementAndGet());
	}

	private final class ChatUser extends MessageInbound {

		private final String username;

		private ChatUser(int id) {
			this.username = "guest #" + id;
		}

		@Override
		protected void onOpen(WsOutbound outbound) {
			connections.add(this);
			String message = username + " has joined the chat";
			broadcast(message);
		}

		@Override
		protected void onClose(int status) {
			connections.remove(this);
			String message = username + " has left the chat";
			broadcast(message);
		}

		@Override
		protected void onBinaryMessage(ByteBuffer message) throws IOException {
			throw new UnsupportedOperationException(
					"binary messages are not supported");
		}

		@Override
		protected void onTextMessage(CharBuffer message) throws IOException {
			// it would be best filter the message
			// ...
			String str = username + ": " + message;
			broadcast(str);
		}

		private void broadcast(String message) {
			for (ChatUser connection : connections) {
				try {
					CharBuffer buffer = CharBuffer.wrap(message);
					connection.getWsOutbound().writeTextMessage(buffer);
				} catch (IOException ignore) {
					// ...
				}
			}
		}
	}
}

The following video clip overviews the source code of these two files, shows their execution using the Apache Tomcat and explains everything step by step.

You can find more slides, video clips and code samples for using HTML5 WebSockets API and for using Java EE support for WebSockets API in my free (for personal and academic usage) courses at http://abelski.lifemichael.com.

Share:

The Visitor Design Pattern

The Visitor Design Pattern

The visitor design pattern allows us to add operations to objects that already exist without modifying their classes and without extending them.

What are Anti Patterns?

Anti Patterns

Unlike design patterns, anti patterns just seem to be a solution. However, they are not a solution and they cause additional costs.

Virtual Threads in Java Professional Seminar

Virtual Threads in Java

The use of virtual threads can assist us with improving the performance of our code. Learn how to use virtual threads effectively.

NoSQL Databases Courses, Seminars, Consulting, and Development

MongoDB Design Patterns Meetup

The use of MongoDB involves with various cases in which we can overcome performance issues by implementing specific design patterns.

image of woman and database

Record Classes in Java

Learn how to define record classes in Java, and when to use record classes in your code. Stay up to date with the new Java features.

Accessibility | Career | Conferences | Design Patterns | JavaScript | Meetups | PHP | Podcasts | Python | Self Learning

Teaching Methodologies | Fullstack | C++ | C# | CSS | Node.js | Angular | Java | Go | Android | Kotlin | Swift | Academy

Front End Development | Scala | Architectures | Cloud | Big Data | Internet of Things | Kids Learn Programming

The Beauty of Code

Coding is Art! Developing Code That Works is Simple. Develop Code with Style is a Challenge!

Skip to content Update cookies preferences