Overview
Horse Trust uses Socket.io to provide instant, bidirectional communication between buyers and sellers. The chat system includes conversation management, real-time message delivery, typing indicators, and read receipts.Architecture
The real-time chat system is built on three main components:Conversations
Two-participant channels linked to horse listings
Messages
Persistent chat messages with read status
Socket.io Server
WebSocket server for real-time events
Data Models
Conversation Model
Defined inserver/src/models/VetRecord.ts:
Conversations are strictly two-participant to maintain clear buyer-seller communication.
Message Model
Last Message Snapshot
Conversations store a snapshot of the last message for quick list rendering:Socket.io Server Setup
The Socket.io server is configured inserver/src/index.ts:
CORS Configuration
string | string[]
Comma-separated list of allowed origins from
CORS_ORIGINS environment variableboolean
default:true
Allow credentials (cookies, authorization headers) in cross-origin requests
JWT Authentication Middleware
All Socket.io connections must be authenticated:1
Extract Token
Client passes JWT token in
socket.handshake.auth.token2
Verify Signature
Token is verified against
JWT_SECRET environment variable3
Attach User Data
Decoded user data is attached to socket instance for use in handlers
4
Reject Unauthorized
Invalid or missing tokens result in connection rejection
Connection Handling
User Rooms
Each authenticated user automatically joins a personal room:Event Handlers
Join Conversation
Users join conversation-specific rooms to receive messages:Send Message
The core messaging logic with full error handling:Database Persistence
Database Persistence
Messages are immediately persisted to MongoDB before being broadcast.
Conversation Update
Conversation Update
The conversation’s
last_message field is updated for efficient list rendering.Dual Broadcast
Dual Broadcast
Messages are sent to both the conversation room (for open chats) and recipient’s personal room (for notifications).
Acknowledgment
Acknowledgment
The callback function confirms successful delivery to the sender.
Typing Indicators
Real-time typing indicators enhance the chat experience:Note the use of
socket.to() instead of io.to() - this broadcasts to all sockets in the room except the sender.Client-Side Integration
Connecting to Socket.io
Joining a Conversation
Sending Messages
Receiving Messages
Typing Indicators
Read Receipts
Implement read receipts by emitting a read event when messages are viewed:Disconnection Handling
Client-Side Reconnection
Best Practices
Authentication Required
Always verify JWT tokens before allowing socket connections
Participant Validation
Check user is authorized to send messages in a conversation
Database First
Persist messages before broadcasting to ensure durability
Acknowledgments
Use acknowledgment callbacks for critical operations
Room Management
Properly join/leave rooms to prevent memory leaks
Error Handling
Gracefully handle all errors with user feedback
Performance Considerations
Message History Pagination
Message History Pagination
Load messages in batches (e.g., 50 at a time) and implement infinite scroll for long conversations.
Typing Throttle
Typing Throttle
Throttle typing indicator events to reduce unnecessary broadcasts (max once per second).
Connection Pooling
Connection Pooling
Use connection pooling for database queries in high-traffic scenarios.
Redis Adapter
Redis Adapter
For horizontal scaling, use Redis adapter to enable cross-server communication:
Next Steps
Message History API
Load conversation history via REST API
Notification System
Implement push notifications for offline users

