🌐 Jakarta WebSocket Endpoints: The Magic of Real-Time Chat
Imagine you and your best friend have two tin cans connected by a string. You can talk back and forth instantly—no waiting, no letters, no email! That’s what WebSocket does for websites.
🎯 What We’ll Learn
Think of a pizza delivery app. Every time the delivery person moves, your phone updates instantly. No refreshing. No waiting. That’s WebSocket magic!
Today, we’ll learn:
- What Jakarta WebSocket is (our magic phone line)
- WebSocket Endpoints (the phone stations)
- Two ways to build them (easy vs. detailed)
- WebSocket Sessions (the actual phone call)
📞 Jakarta WebSocket Overview
The Problem: Playing Catch Alone
Imagine playing catch, but you throw the ball, then wait… and wait… until someone throws it back. That’s how normal web pages work. You ask a question (HTTP request), then wait for an answer.
The Solution: A Magic Walkie-Talkie
WebSocket is like having walkie-talkies! Both people can talk whenever they want. No waiting. No taking turns.
Normal Web (HTTP):
You → Server → You wait → Server replies
WebSocket:
You ↔ Server (talk anytime!)
Why Jakarta WebSocket?
Jakarta WebSocket is Java’s official way to build these walkie-talkies. It’s part of Jakarta EE—like a big toolbox for building web apps.
graph TD A["📱 Your Phone"] <-->|WebSocket| B["🖥️ Server"] B <-->|WebSocket| C[📱 Friend's Phone] style A fill:#e3f2fd style B fill:#fff3e0 style C fill:#e8f5e9
Real-life examples:
- 💬 Chat apps (WhatsApp, Discord)
- 🎮 Online games
- 📈 Stock tickers
- 🚗 Uber driver tracking
🚉 WebSocket Endpoints
What’s an Endpoint?
An endpoint is like a phone booth. It’s a specific place where people can connect and start talking.
When you dial a number, you reach a specific phone. When a browser connects to a WebSocket, it reaches a specific endpoint.
The URL is the Phone Number
ws://myapp.com/chat
└── This is the endpoint!
Every endpoint has:
- A path (like
/chator/game) - Handlers for events (someone calls, someone talks, someone hangs up)
The Four Big Events
Every phone call has these moments:
| Event | What Happens | Like… |
|---|---|---|
| Open | Connection starts | 📞 “Hello?” |
| Message | Someone talks | 🗣️ “How are you?” |
| Error | Something breaks | ⚠️ Static on the line |
| Close | Call ends | 👋 “Goodbye!” |
🎨 Annotated Endpoints (The Easy Way)
What Are Annotations?
Think of annotations as sticky notes on your code. They tell Java: “Hey, this is special!”
An annotated endpoint uses these sticky notes to create WebSocket connections—super easy!
Building Your First Chat Endpoint
@ServerEndpoint("/chat")
public class ChatEndpoint {
@OnOpen
public void onOpen(Session session) {
System.out.println("New friend joined!");
}
@OnMessage
public void onMessage(String msg,
Session session) {
System.out.println("Got: " + msg);
}
@OnClose
public void onClose(Session session) {
System.out.println("Friend left!");
}
@OnError
public void onError(Throwable error) {
System.out.println("Oops: " + error);
}
}
The Magic Annotations
| Annotation | Meaning | Emoji |
|---|---|---|
@ServerEndpoint("/path") |
“This is my phone booth!” | 📞 |
@OnOpen |
“Someone’s calling!” | 🔔 |
@OnMessage |
“They said something!” | 💬 |
@OnClose |
“They hung up!” | 👋 |
@OnError |
“Line’s broken!” | ⚠️ |
Why It’s Easy
You just write normal Java methods. The annotations do all the wiring. Like having a robot assistant connect the wires for you!
graph TD A["🏷️ @ServerEndpoint"] --> B["Creates endpoint at /chat"] C["🏷️ @OnOpen"] --> D["Runs when someone connects"] E["🏷️ @OnMessage"] --> F["Runs when message arrives"] G["🏷️ @OnClose"] --> H["Runs when disconnected"]
🔧 Programmatic Endpoints (The Detailed Way)
When Easy Isn’t Enough
Sometimes you need more control. Like building a custom phone instead of buying one.
Programmatic endpoints let you configure everything by writing code—no annotations!
Building It Step-by-Step
Step 1: Create Your Endpoint Class
public class MyEndpoint extends Endpoint {
@Override
public void onOpen(Session session,
EndpointConfig config) {
System.out.println("Connected!");
// Add message handler
session.addMessageHandler(
new MessageHandler.Whole<String>() {
public void onMessage(String msg) {
System.out.println("Got: " + msg);
}
}
);
}
@Override
public void onClose(Session session,
CloseReason reason) {
System.out.println("Closed: " + reason);
}
}
Step 2: Configure It
public class MyConfig
implements ServerApplicationConfig {
public Set<ServerEndpointConfig>
getEndpointConfigs(...) {
ServerEndpointConfig config =
ServerEndpointConfig.Builder
.create(MyEndpoint.class, "/chat")
.build();
return Set.of(config);
}
}
Annotated vs. Programmatic
| Feature | Annotated 🎨 | Programmatic 🔧 |
|---|---|---|
| Ease | Super easy | More work |
| Flexibility | Good | Maximum |
| Code size | Small | Larger |
| Best for | Most apps | Complex needs |
When to Use Programmatic?
- Dynamic paths (e.g.,
/chat/{roomId}) - Custom security checks
- Special message encoders
- Advanced configuration
📱 WebSocket Session
What’s a Session?
A Session is your actual phone call. It holds everything about the current connection:
- Who’s on the line
- How to send messages
- Connection settings
The Session Object
When someone connects, Java gives you a Session object. It’s your remote control!
@OnOpen
public void onOpen(Session session) {
// Get session ID
String id = session.getId();
// Check if connection is open
boolean open = session.isOpen();
// Send a message back
session.getBasicRemote()
.sendText("Welcome!");
}
Session Powers
| Method | What It Does |
|---|---|
getId() |
Get unique session ID |
isOpen() |
Check if connected |
getBasicRemote() |
Send messages (waits) |
getAsyncRemote() |
Send messages (doesn’t wait) |
close() |
End the connection |
getUserProperties() |
Store custom data |
Sending Messages
Two ways to send:
// Way 1: Basic (waits until sent)
session.getBasicRemote()
.sendText("Hello!");
// Way 2: Async (sends in background)
session.getAsyncRemote()
.sendText("Hello!");
Storing Data in Session
Each session can hold your own data—like a backpack!
@OnOpen
public void onOpen(Session session) {
// Store user's name
session.getUserProperties()
.put("username", "Alex");
}
@OnMessage
public void onMessage(String msg,
Session session) {
// Get user's name
String name = (String) session
.getUserProperties()
.get("username");
System.out.println(name + ": " + msg);
}
Broadcasting to Everyone
@OnMessage
public void broadcast(String message,
Session sender) {
// Get all connected sessions
for (Session s : sender.getOpenSessions()) {
if (s.isOpen()) {
s.getBasicRemote()
.sendText(message);
}
}
}
graph TD A["📱 Session A"] --> B["🖥️ Server"] C["📱 Session B"] --> B D["📱 Session C"] --> B B -->|Broadcast| A B -->|Broadcast| C B -->|Broadcast| D style B fill:#fff3e0
🎉 Putting It All Together
A Simple Chat Room
@ServerEndpoint("/chat/{room}")
public class ChatRoom {
@OnOpen
public void join(
Session session,
@PathParam("room") String room) {
session.getUserProperties()
.put("room", room);
System.out.println("Joined: " + room);
}
@OnMessage
public void chat(String msg,
Session session) {
String room = (String) session
.getUserProperties().get("room");
// Send to all in same room
for (Session s : session
.getOpenSessions()) {
String theirRoom = (String) s
.getUserProperties()
.get("room");
if (room.equals(theirRoom)) {
s.getBasicRemote()
.sendText(msg);
}
}
}
}
🧠 Quick Recap
| Concept | What It Is | Remember As |
|---|---|---|
| Jakarta WebSocket | Java’s real-time tool | The walkie-talkie |
| Endpoint | Connection point | Phone booth |
| Annotated | Easy way with @tags | Sticky notes |
| Programmatic | Detailed code way | Build your own |
| Session | Active connection | The call itself |
🚀 You Did It!
You now understand how real-time apps work behind the scenes. Every time you send a message on WhatsApp or see a driver moving on Uber—that’s WebSocket!
Next time you use a chat app, you’ll know the magic inside. 🌟
“The best way to learn is to understand the story behind the code.”
