WebSockets
JAVA EE
Java EE WebSockets – Communication in Real-Time
• Section 8 Overview
• Learn how to build real-time, full-duplex communication
between client and server.
• Topics: Annotated & Programmatic Endpoints, URI
Templates, Encoders/Decoders, and Sample Code.
Introduction to WebSockets
• WebSockets provide a full-duplex communication channel
over a single TCP connection.
• Unlike HTTP (request-response), WebSocket allows
bidirectional data exchange.
• Ideal for chat apps, live dashboards, gaming, and
notifications.
WebSocket Lifecycle
• Opening handshake: Client requests connection upgrade
from HTTP to WebSocket.
• Connection open: Both sides can send messages
anytime.
• Data exchange: Text/Binary messages flow in both
directions.
• Connection close: Either side can close the connection
gracefully.
Java EE WebSocket API
• Introduced in Java EE 7 (JSR 356).
• Main packages:
• - [Link] → Core API.
• - [Link] → Server endpoint annotations
and config.
• Supported on servers like Payara, GlassFish, WildFly, etc.
Annotated Endpoints Overview
• Easiest way to create WebSocket endpoints.
• Use annotations:
• - @ServerEndpoint – Defines the endpoint URI.
• - @OnOpen, @OnMessage, @OnClose, @OnError –
Handle WebSocket events.
• Automatically managed by the container.
Annotated Endpoint Example
• @ServerEndpoint("/chat")
• public class ChatEndpoint {
• @OnOpen public void onOpen(Session s){
[Link]("Connected: "+[Link]()); }
• @OnMessage public void onMessage(String msg, Session s){
[Link](msg); }
• @OnClose public void onClose(Session s){
[Link]("Disconnected: "+[Link]()); }
• }
Programmatic Endpoints Overview
• More flexible than annotations.
• Extend Endpoint class manually.
• Allows custom configuration and message handlers.
• Suitable when endpoints are dynamically registered.
Programmatic Endpoint Example
• @ServerEndpoint("/notify")
• public class NotifyEndpoint extends Endpoint {
• @Override public void onOpen(Session s,
EndpointConfig cfg) {
• [Link]([Link], msg ->
[Link]("Received: "+msg));
• }
• }
WebSocket Resources
• WebSocket resources include:
• - Client Sessions – Manage connected clients.
• - Message Handlers – Handle text/binary/pong
messages.
• - Configuration – Custom encoders, decoders, and
endpoint configs.
• Resources are automatically injected into endpoints.
Using URI Templates
• Allows parameters in endpoint paths.
• @ServerEndpoint("/chat/{roomId}")
• public class RoomEndpoint {
• @OnOpen public void onOpen(Session s,
@PathParam("roomId") String roomId){
• [Link]("Joined Room: "+roomId);
• }
• }
• Dynamically identifies rooms or user sessions.
Encoders and Decoders Overview
• Used to convert Java objects ↔ JSON/Text messages.
• Encoder → Converts object → String or binary.
• Decoder → Converts message → Java object.
• Helps structure messages in a clear format.
Encoder and Decoder Example
• public class Message { private String user; private String content; }
• public class MessageEncoder implements [Link]<Message> {
• public String encode(Message m){ return
[Link]()+":"+[Link](); } }
• public class MessageDecoder implements [Link]<Message> {
• public Message decode(String s){ String[] p=[Link](":"); return new
Message(p[0],p[1]); } }
WebSocket Summary
• WebSocket enables real-time bi-directional
communication.
• Two endpoint types: Annotated & Programmatic.
• Encoders/Decoders simplify message handling.
• URI Templates help manage dynamic routes.
• Useful for chats, notifications, dashboards, IoT, etc.
Advantages of WebSockets
• ✅ Full-duplex communication
• ✅ Reduced latency (no repeated HTTP requests)
• ✅ Lower bandwidth usage
• ✅ Easy integration with Java EE servers
• ✅ Ideal for event-driven applications
Sample Code Run
• Demo Output (Payara / GlassFish):
• Connected: Session 1
• Message from client: Hello Server!
• Server response: Welcome to WebSocket!
• Disconnected: Session 1
• Files involved:
• - [Link] (Client)
• - [Link] (Server Endpoint)
• - [Link] (Deployment Descriptor)
Folder Structure
JavaEEWebSocketDemo/
├── src/
│ └── com/example/websocket/
│ └── [Link]
├── WebContent/
│ ├── [Link]
│ └── WEB-INF/
│ └── [Link]
1. [Link] (Server Endpoint) @OnMessage
package [Link];
public void onMessage(String message, Session
session) {
import [Link];
[Link]("Message from " +
import [Link];
[Link]() + ": " + message);
import [Link]; sendMessageToAll("User " + [Link]() + ": "
import [Link]; + message);
import [Link]; }
import [Link]; @OnClose
import [Link]; public void onClose(Session session) {
import [Link]; [Link](session);
import [Link]; [Link]("Disconnected: " +
[Link]());
@ServerEndpoint("/chat") sendMessageToAll("User " + [Link]() + "
public class ChatEndpoint {
left the chat!");
}
private void sendMessageToAll(String message) {
private static final Set<Session> chatUsers =
synchronized (chatUsers) {
[Link](new HashSet<>()); for (Session s : chatUsers) {
try {
@OnOpen [Link]().sendText(message);
public void onOpen(Session session) { } catch (IOException e) {
[Link](session); [Link]();
[Link]("Connected: " + [Link]()); }} }}
sendMessageToAll("User " + [Link]() + " joined }
the chat!");
}
// Connect to WebSocket endpoint
const ws = new
2. [Link] (Client Page) WebSocket("[Link]
<!DOCTYPE html> mo/chat"); [Link] = () => appendMessage("✅
<html><head>
Connected to the chat server.");
[Link] = (event) =>
<meta charset="UTF-8"> appendMessage([Link]);
<title>Java EE WebSocket Chat</title> [Link] = () => appendMessage("❌ Connection
<style> closed.");
body { font-family: Arial; margin: 30px; background-color: [Link] = sendMessage;
#f2f2f2; }
[Link]("keypress", e => {
if ([Link] === "Enter") sendMessage();
#chatArea { border: 1px solid #ccc; padding: 10px; height: });
300px; overflow-y: scroll; background: #fff; } function sendMessage() {
#message { width: 80%; padding: 10px; } const msg = [Link]();
#sendBtn { padding: 10px 20px; } if (msg) {
</style></head> [Link](msg);
[Link] = "";
<body> }}
<h2>💬 Java EE WebSocket Chat</h2> function appendMessage(msg) {
<div id="chatArea"></div> const p = [Link]("p");
<br> [Link] = msg;
[Link](p);
<input type="text" id="message" placeholder="Type your [Link] = [Link];
message..." /> }</script></body></html>
<button id="sendBtn">Send</button>
<script>
const chatArea = [Link]("chatArea");
const messageInput = [Link]("message");
const sendBtn = [Link]("sendBtn");
3. [Link] (Deployment Descriptor)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="[Link]
xmlns:xsi="[Link]
xsi:schemaLocation="[Link]
[Link]
version="3.1">
<display-name>JavaEE WebSocket Demo</display-name>
<welcome-file-list>
<welcome-file>[Link]</welcome-file>
</welcome-file-list>
</web-app>
How to Run
Import the project into Eclipse IDE for Enterprise Java Developers.
Right-click → Run on Server → choose Payara / GlassFish / WildFly.
Open browser and go to:
👉 [Link]
Open two browser tabs — type messages in one and watch them appear in both.
Output Example Browser Chat Window:
Console: ✅ Connected to the chat server.
Connected: Session1 User Session1 joined the chat!
Message from Session1: Hello User Session1: Hello
Disconnected: Session1
User Session1 left the chat!