NexChat: The Spring Boot Chat Stack That Treats Messaging, Calls, and AI Summaries as One System
A real-time Java backend that uses WebSockets for chat, WebRTC signaling for calls, and Gemini for conversation summaries, all wrapped in JWT security and rate limits.
- NexChat’s main idea is consolidation: text chat, WebRTC signaling, and AI summaries all share one real-time spine.
- The WebSocket layer is doing more than broadcasting messages, because it also authenticates socket sessions and routes peer-to-peer call signals.
- The AI summary feature is bounded by design, with rate limiting and message-windowing preventing it from becoming an expensive novelty.
- The security stack reads like a product layer, with JWTs, refresh tokens, OTP verification, BCrypt, and explicit socket-time token checks.
Why NexChat Is More Than a Chat App
Most chat backends solve one problem: move text from one user to another. NexChat stretches that idea into something larger. It treats chat as a communication control plane, where the same backend handles room broadcasts, WebRTC signaling, and AI-generated summaries.
That matters because these are not the same kind of workload. Broadcast chat wants fan-out. WebRTC signaling wants precise user-to-user routing. Summarization wants bounded batch processing. NexChat puts all three under one Spring Boot roof instead of scattering them across separate services.
The repo also shows a clear bias toward production habits. JWT access and refresh tokens, WebSocket authentication at connect time, OTP verification, BCrypt, rate limiting, Actuator, and structured DTO mapping all suggest a backend that is trying to behave like a product, not a demo.
The Real-Time Core: Messages and WebRTC Signaling Share the Same Spine
The real surprise in NexChat is that the WebSocket layer is not just a chat pipe. It is the transport spine for two distinct real-time jobs: group messaging and WebRTC signaling. That keeps the real-time surface area small, even while the product surface grows.
@MessageMapping("/chat.send")
public void sendMessage(@Payload ChatMessageDto message) {
chatService.save(message);
messagingTemplate.convertAndSend("/topic/room." + message.getRoomId(), message);
}
@MessageMapping("/webrtc.signal")
public void handleWebRtcSignal(@Payload WebRtcRequest request) {
messagingTemplate.convertAndSendToUser(
request.getTargetUserId(),
"/queue/webrtc",
request
);
}