A real-time chat application built with Spring Boot and WebSockets that allows users to communicate with each other directly. The application supports user registration, authentication, and real-time messaging with offline message delivery.
- Real-time messaging using WebSocket connections
- User registration and authentication with simple username/password
- Online user tracking with live status updates
- Direct messaging between users
- Offline message delivery - messages sent to offline users are stored and delivered when they come back online
- Session management - tracks active WebSocket connections per user
- H2 in-memory database for data persistence during runtime
- Spring Boot 3.2.0 with WebSocket support
- Raw WebSocketHandler implementation (no STOMP abstractions)
- SockJS for enhanced browser compatibility and fallback support
- H2 Database for storing users and undelivered messages
- Spring Data JPA for database operations
- Spring Security configured for API access
- Pure HTML/JavaScript frontend with no client-side frameworks
- Registration/Login: Users register with a username and password or login with existing credentials
- WebSocket Connection: Upon successful login, a WebSocket connection is established
- Authentication: The client authenticates over WebSocket by sending username
- Online Status: The server tracks active sessions and broadcasts online user lists
- Messaging: Users select recipients from the online users list and send messages
- Message Delivery:
- If recipient is online: Message delivered immediately via WebSocket
- If recipient is offline: Message stored in database as undelivered
- Offline Message Delivery: When users come back online, all undelivered messages are sent
- Historical Messages: When users come back online, the whole conversation history is fetched
authenticate
: Client authenticates with usernamechat
: Send a message to another userget_users
: Request current online users listmessage
: Receive a message from another useronline_users
: Receive updated list of online usersmessage_sent
: Confirmation that message was sent/queued
- Users Table: id, username, password, created_at, last_login
- Messages Table: id, sender_username, recipient_username, content, sent_at, delivered, delivered_at
- WebSocket sessions are stored in a
ConcurrentHashMap
with username as key - Sessions are cleaned up when connections close or errors occur
- Online user lists are broadcast to all connected clients when users join/leave
- All messages are stored in the database regardless of delivery status
- Undelivered messages are marked with
delivered = false
- When delivered, messages are marked with
delivered = true
anddelivered_at
timestamp - Messages are delivered in chronological order (oldest first)
POST /api/auth/register
- Register new userPOST /api/auth/login
- Login userGET /api/auth/users
- Get all registered users
/websocket/chat
- Main WebSocket endpoint with SockJS support
- Build the application: Clone the code and perform a
mvn clean isntall
. - Start the application: Run the Spring Boot application -
mvn spring-boot:run
- Access the chat: Open browser to
http://localhost:8080
- Register users: Create multiple user accounts for testing
- Login and chat: Login with different users in multiple browser tabs/windows
- Test offline messaging: Close one browser tab, send messages to that user, then reopen to see message delivery
- Message History: Fetches conversation history for each user
- Monitor database: Access H2 console at
http://localhost:8080/h2-console
(URL:jdbc:h2:mem:chatdb
, user:sa
, password:password
)
We are not using ws anywhere for WebSocket URL - one that starts with ws://.
The frontend is using SockJS, not raw WebSocket URLs. In the JavaScript code, it creates the connection with:
socket = new SockJS(baseUrl);
Where baseUrl is constructed as the HTTP URL (http:// or https://) + host + /websocket/chat.
SockJS handles the protocol negotiation internally and will use WebSocket (ws:// or wss://) when available, but the client code uses the HTTP-based SockJS endpoint. The raw WebSocket URL would be something like ws://localhost:8080/websocket/chat but SockJS abstracts this away. This application demonstrates a complete real-time chat system with robust offline message handling, making it suitable for both development learning and as a foundation for more complex messaging applications.
- Login and Register are sketchy, you do a Register first and then Login on the same page.
- Refreshing the windows logs you out.
- If the user logs out, the other user can send messages until the chat window of the logged out use is selected, after that you cannot select it again.
(can be more :))