πŸ’¬ Chat Service

Github: github.com/le-minh-duc-dev/chat-system-chat-service.git

The Chat Service enables real-time messaging, room management, and user presence tracking for the Chat System. It uses WebSocket with STOMP for live communication, Redis for presence caching, and Kafka for scaling message delivery across service instances.


πŸ“œ Features

  • Real-Time Messaging via STOMP
    Enables WebSocket-based communication for chat messages and in-app events.
    Supports 1-to-1 and group messages with delivery status tracking.

  • Distributed Messaging via Kafka
    Kafka ensures message delivery across multiple instances of Chat Service.

  • Room Management
    Create, list, and join chat rooms. Rooms can be public or private, with custom metadata.

  • User Presence & Online Status
    Users send heartbeat pings to indicate active status. Online status is cached in Redis.

  • Presence Event Broadcasting
    Notify other users in the same room when someone joins, disconnects, or reconnects.

  • Last-Seen Per-Room Tracking Records the last active timestamp for each user per chat room. Used to load unread messages and generate notification badges or "new messages" indicators.


🧰 Technology Stack

  • Spring Boot
  • Spring Data JPA
  • Spring Data Redis
  • Spring Kafka
  • Spring WebSocket (STOMP)
  • Spring Cloud Netflix Eureka
  • Spring Cloud Config
  • Redis
  • Kafka
  • PostgreSQL

πŸ“‚ Endpoints Overview

🌐 REST API (HTTP)

MethodEndpointDescription
POST/api/v1/chat/chat-roomsCreate a new chat room
GET/api/v1/chat/chat-roomsList all chat rooms (pagination supported)
GET/api/v1/chat/chat-rooms/userList rooms joined by the current user
POST/api/v1/chat/chat-rooms/join/{id}Join a specific chat room
GET/internal/chat/chat-rooms/{id}/presence/websocket/users/batchCheck online status of users in a room for other microservices
GET/internal/chat/room_last_seen?chatRoomId={id}&userId={id}Get the last seen timestamp of a user in a specific room (used for unseen message logic)

πŸ“‘ WebSocket (STOMP)

DestinationDescription
/app/chat.send/{chatroomId}Send message to a chatroom
/app/heartbeatHeartbeat ping to keep presence alive
/app/unsubscribe/chat_rooms/{chatroomId}Called when user leaves a chatroom tab (tracks last seen)
/user/queue/errorsReceive error messages from server
/user/queue/heartbeatReplyReceive pong response to heartbeat

🧠 How the Chat System Works


πŸ“¦ Kafka Topics

  • chat-messages – Published by the Chat Service when a user sends a message, consumed by the Message Service for persistence, and also consumed by all Chat Service instances to deliver the message to connected WebSocket clients.
  • command-messages – Used for sending system-level commands to the client application, such as updates.
  • presence-messages – Broadcast online/offline status changes to other clients.

Configured partitions and replicas via application.yml:


🧾 Data Contracts

ChatRoomDTO

{
  "id": 1,
  "name": "Dev Chatroom",
  "description": "Chat for developers",
  "type": "GROUP",
  "status": "ACTIVE",
  "ownerId": 123,
  "createdAt": "2025-04-29T10:00:00Z",
  "updatedAt": "2025-04-29T10:00:00Z"
}

ClientMessageDTO

{
  "content": "Hello from STOMP!"
}

MessageDTO

{
  "id": 948359823823823,
  "senderId": 1,
  "roomId": 1,
  "content": "Hello!",
  "type": "GROUP",
  "timestamp": "2025-04-29T15:23:00Z"
}

BasicUserInfoDTO

{
  "id": 1,
  "username": "john.doe",
  "isOnline": true
}

UserPresenceDTO

{
  "id": 1,
  "isOnline": false
}

πŸ—„οΈ Redis Key Patterns

PurposeRedis Key Format
Presence trackingpresence:user:{userId}
WebSocket trackingwebsocket:user:{userId}
Last-Seen Per-Room Trackingactive_room:user:{userId}

πŸ” Security

  • Authentication
    JWT token (from Auth Service) required for WebSocket connections.

  • Authorization Headers
    Custom header X-User-UserId is passed by API Gateway to identify user across services.


πŸš€ Scaling Notes

  • Stateless Design:
    Chat Service instances are stateless; Redis handles shared state (e.g., online presence).

  • WebSocket Sessions:
    Each instance manages its own WebSocket sessions. Kafka ensures consistent messaging across instances.

  • Load Balanced:
    Chat Service is registered with Eureka and can be scaled horizontally behind API Gateway.



πŸ’¬ "Turning ideas into scalable code."

Β© 2025 LΓͺ Minh Đức. Stay curious.