Of course! This is a very common and powerful combination for building modern, real-time web applications. Here’s a comprehensive guide covering both the Java (Server) and HTML5 (Client) sides of a WebSocket connection, complete with code examples.
What is WebSocket?
WebSocket is a computer communication protocol that provides full-duplex communication channels over a single, long-lived TCP connection. Unlike traditional HTTP, which is request-response-based, WebSocket allows the server to push data to the client at any time.
Key Advantages:
- Real-time: True bi-directional communication.
- Efficient: No repeated HTTP request/response headers, reducing overhead.
- Low Latency: Data is sent as soon as it's available.
The Client-Side: HTML5 & JavaScript
The client-side implementation is straightforward using the browser's built-in WebSocket API.
Key Concepts:
new WebSocket(url): Creates a new WebSocket connection.onopen: A function called when the connection is successfully established.onmessage: A function called when a message is received from the server.onerror: A function called when an error occurs.onclose: A function called when the connection is closed.send(data): Sends data to the server.close(): Closes the connection.
Example: index.html
This simple web page will connect to our Java server, send a message, and display messages received from the server.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">Java WebSocket Client</title>
<style>
body { font-family: sans-serif; }
#messages { border: 1px solid #ccc; padding: 10px; height: 300px; overflow-y: scroll; margin-bottom: 10px; }
#input { width: 80%; padding: 5px; }
#sendButton { padding: 5px 10px; }
</style>
</head>
<body>
<h1>Java WebSocket Chat</h1>
<div id="messages"></div>
<div>
<input type="text" id="input" placeholder="Type a message...">
<button id="sendButton">Send</button>
</div>
<script>
// 1. Create a new WebSocket connection.
// 'ws://' for non-secure, 'wss://' for secure (HTTPS)
const socket = new WebSocket('ws://localhost:8080/websocket/chat');
const messagesDiv = document.getElementById('messages');
const inputElement = document.getElementById('input');
const sendButton = document.getElementById('sendButton');
// 2. Connection opened
socket.onopen = function(event) {
console.log("Connection established!");
appendMessage("System: Connected to the server.");
};
// 3. Listen for messages
socket.onmessage = function(event) {
console.log("Message from server: ", event.data);
appendMessage(event.data);
};
// 4. Handle errors
socket.onerror = function(error) {
console.error("WebSocket Error: ", error);
appendMessage("System: An error occurred.");
};
// 5. Connection closed
socket.onclose = function(event) {
if (event.wasClean) {
console.log(`Connection closed cleanly, code=${event.code} reason=${event.reason}`);
} else {
console.error('Connection died');
}
appendMessage("System: Connection closed.");
};
// Function to append a message to the div
function appendMessage(message) {
const p = document.createElement('p');
p.textContent = message;
messagesDiv.appendChild(p);
messagesDiv.scrollTop = messagesDiv.scrollHeight; // Auto-scroll
}
// Send message when the button is clicked or Enter is pressed
function sendMessage() {
const message = inputElement.value;
if (message) {
console.log("Sending message: ", message);
socket.send(message);
inputElement.value = '';
}
}
sendButton.addEventListener('click', sendMessage);
inputElement.addEventListener('keypress', function(event) {
if (event.key === 'Enter') {
sendMessage();
}
});
</script>
</body>
</html>
The Server-Side: Java
For Java, the modern and standard way to handle WebSockets is using the Jakarta WebSocket (formerly Java WebSocket) API. We'll use a simple Servlet-based approach, which is easy to set up in any standard Java web server (like Tomcat, Jetty, etc.).


Key Concepts:
@ServerEndpoint: An annotation that marks a class as a WebSocket endpoint. The value is the URL path for the endpoint.@OnOpen: A method annotated with this will be called when a new WebSocket connection is established.@OnClose: Called when a connection is closed.@OnMessage: Called when a message is received from a client.@OnError: Called when an error occurs.Session: Represents the two-way communication channel with a client. It's used to send messages back (session.getBasicRemote().sendText(...)).
Project Setup (using Maven)
You'll need the Jakarta WebSocket API dependency. For a server like Tomcat 10 or newer, this is usually included, but it's good to be explicit.
<dependencies>
<!-- Jakarta WebSocket API -->
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-web-api</artifactId>
<version>10.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
Example: ChatEndpoint.java
This is the main WebSocket endpoint class.
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* WebSocket endpoint for a simple chat application.
* The path "/websocket/chat" must match the client's WebSocket URL.
*/
@ServerEndpoint("/websocket/chat")
public class ChatEndpoint {
// A thread-safe Set to store all active sessions.
// This allows us to broadcast messages to all connected clients.
private static final Set<Session> chatroomUsers = Collections.synchronizedSet(new HashSet<>());
/**
* Called when a new WebSocket connection is opened.
* @param session The session for the new connection.
*/
@OnOpen
public void onOpen(Session session) {
chatroomUsers.add(session);
System.out.println("New connection opened. Session ID: " + session.getId());
// Broadcast a message to all users that someone joined
broadcast("System: User " + session.getId() + " has joined the chat.");
}
/**
* Called when a message is received from a client.
* @param message The message received from the client.
* @param session The session of the client who sent the message.
*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("Message from " + session.getId() + ": " + message);
// Broadcast the received message to all other users
broadcast("User " + session.getId() + ": " + message);
}
/**
* Called when a WebSocket connection is closed.
* @param session The session that is being closed.
* @param closeReason The reason for the closure.
*/
@OnClose
public void onClose(Session session, CloseReason closeReason) {
chatroomUsers.remove(session);
System.out.println("Connection closed. Session ID: " + session.getId() + ", Reason: " + closeReason.getReasonPhrase());
// Broadcast a message to all users that someone left
broadcast("System: User " + session.getId() + " has left the chat.");
}
/**
* Called when an error occurs during the WebSocket communication.
* @param session The session where the error occurred.
* @param throwable The throwable that was thrown.
*/
@OnError
public void onError(Session session, Throwable throwable) {
System.err.println("Error on session " + session.getId());
throwable.printStackTrace();
chatroomUsers.remove(session);
}
/**
* Helper method to send a message to all connected clients.
* @param message The message to broadcast.
*/
private void broadcast(String message) {
// Iterate over a copy of the set to avoid ConcurrentModificationException
Set<Session> usersCopy = new HashSet<>(chatroomUsers);
for (Session user : usersCopy) {
try {
// Check if the session is still open
if (user.isOpen()) {
user.getBasicRemote().sendText(message);
}
} catch (IOException e) {
System.err.println("Error broadcasting message to user " + user.getId());
e.printStackTrace();
// If an error occurs sending to a user, remove them from the set
chatroomUsers.remove(user);
}
}
}
}
Putting It All Together: Running the Application

