#
WebSockets
QuickDapp uses WebSockets for real-time communication between the server and connected clients. When the application creates a notification, it gets saved to the database and immediately pushed to the user's browser sessions.
#
How It Works
Clients connect to /ws after authenticating. They send a registration message with their JWT token, and the server associates that connection with their user ID. From then on, any notification created for that user gets delivered instantly.
The SocketManager tracks two mappings: client IDs to WebSocket connections, and user IDs to sets of client IDs. A single user can have multiple browser tabs open, and each receives the same notifications.
When a worker process creates a notification, it sends an IPC message to the main server process, which then routes the message through the SocketManager to the user's connected clients.
#
Connection Lifecycle
- Client establishes WebSocket connection to
/ws - Server sends a
Connectedmessage confirming the connection - Client sends
registerwith JWT token - Server validates the token and associates the connection with the user
- Server sends
Registeredconfirmation - Server pushes
NotificationReceivedmessages as notifications are created - On disconnect, server removes the client from its tracking maps
#
Message Types
Messages are defined in src/shared/websocket/types.ts:
Connected— Initial connection acknowledgmentRegistered— User registration successfulNotificationReceived— New notification with id, userId, data, createdAt, readError— Connection errors (limit exceeded, invalid token)
#
Connection Limits
The server enforces connection limits through configuration:
SOCKET_MAX_TOTAL_CONNECTIONS— Global limit across all usersSOCKET_MAX_CONNECTIONS_PER_USER— Per-user limit
When limits are exceeded, the connection receives an Error message and closes.
#
Client Usage
The frontend's SocketContext handles the connection automatically. It reconnects when authentication state changes and provides a subscribe() method for listening to specific message types:
const { subscribe } = useSocket()
useEffect(() => {
return subscribe(WebSocketMessageType.NotificationReceived, (message) => {
// Handle new notification
})
}, [subscribe])
There are no GraphQL subscriptions—all real-time updates flow through this WebSocket connection.
See src/server/ws/index.ts for the server implementation and src/client/lib/socket.ts for the client wrapper.