messaging protocol
FactWebSocket + STOMP
Case Study
Updated: 2025-07-04A full-stack real-time chat application featuring a Spring Boot WebSocket backend with STOMP messaging and MongoDB persistence, paired with a React and Tailwind CSS single-page interface.
messaging protocol
FactWebSocket + STOMP
database
FactMongoDB
security
FactJWT + BCrypt
architecture
FactSpring Boot + React SPA
Minimal infrastructure to get real-time updates to the browser quickly.
Trade-off: SimpleBroker provides low-latency messaging on a single instance but is not horizontally scalable; replacing it with a broker relay (RabbitMQ/ActiveMQ) would be required for multi-instance scaling.
Simplifies authentication from the browser (no manual Authorization header management) and supports cookies across origins for cross-origin frontends.
Trade-off: With CSRF protection disabled (csrf.disable()), this increases CSRF exposure; Authorization header approach reduces CSRF risk but requires client code to manage token storage and attach headers.
Easier to model relational references and reuse User/Message documents.
Trade-off: DBRef causes additional lookups (client/application-managed dereferencing) and can complicate sharding or performance at scale; embedding message docs in channels would reduce lookups but increase duplication.
Provides authenticated, low-latency messaging (direct and channel), persistent message storage, and basic user and channel management for a browser-based chat frontend.
Monolithic Spring Boot application with layered architecture (Controller → Service → Repository), augmented by an event-driven real-time messaging path (STOMP over SockJS WebSockets using Spring’s SimpleBroker).
Key measurable signals: P95_message_delivery_latency_ms (50-250), estimated_throughput_msgs_per_sec_single_instance (200-1000).
| Dimension | Selected Option | Impact | Compromise |
|---|---|---|---|
| Real-time broker | Spring SimpleBroker (in-memory) | Very low operational overhead and low latency on single node. | No cross-instance delivery; not suited for multi-node horizontal scaling. |
| Auth token placement | JWT in HttpOnly cookie (SameSite=None) | Simplifies browser integration and automatic cookie sending for WebSocket handshake. | Increased CSRF risk and cross-origin cookie complexities; requires strict cookie security and CSRF mitigations. |
Failure Path & Recovery Invariants
Possible failure scenarios: MongoDB unreachable: REST endpoints and message persistence fail, controllers return 500; messages not persisted.
Replace the in-memory STOMP broker and on-instance session registry with a broker relay (RabbitMQ/Redis pub/sub) and a centralized session store (Redis) so message delivery and session lookup work across multiple service instances; add sticky-less scaling.
Harden security: remove fallback JWT secret, re-enable CSRF or migrate JWT to Authorization: Bearer header for API requests, add input validation for uploads, sanitize filenames, and add rate limiting/Throttling (API gateway).