WebSocket handlers enable bi-directional real-time communication between client and server. Perfect for chat applications, live collaboration, and gaming.
@org.eclipse.jetty.websocket.api.annotations.WebSocket
@WebSocket("/ws/chat")
public class ChatHandler {
private static final Map<Session, String> users = new ConcurrentHashMap<>();
@OnWebSocketConnect
public void onConnect(Session session) throws IOException {
users.put(session, "anonymous");
session.getRemote().sendString("Welcome to the chat!");
}
@OnWebSocketMessage
public void onMessage(Session session, String message) throws IOException {
for (Session s : users.keySet()) {
if (s.isOpen()) {
s.getRemote().sendString(message);
}
}
}
@OnWebSocketClose
public void onClose(Session session, int code, String reason) {
users.remove(session);
}
}
const ws = new WebSocket('ws://localhost:8080/ws/chat');
ws.onopen = () => {
ws.send('Hello server!');
};
ws.onmessage = (event) => {
console.log('Received:', event.data);
};
ws.onclose = () => {
console.log('Disconnected');
};
Use the /ws/ prefix for WebSocket endpoints to avoid conflicts with HTTP routes.
// ✅ No conflict
@WebSocket("/ws/chat") // WebSocket endpoint
@GET("/chat") // HTTP route (serves the HTML page)
// ❌ Conflict
@WebSocket("/chat") // Conflicts with HTTP route below
@GET("/chat")
WebSocket handlers require both annotations and must be placed in a subpackage of your main package (e.g. websockets/):
@WebSocket("/path") — Obsidian annotation@org.eclipse.jetty.websocket.api.annotations.WebSocket — Jetty annotation