feat: WebSocket presence tracking with page_focus and presence_update
Made-with: Cursor
This commit is contained in:
@@ -32,6 +32,8 @@ class WebSocketManager {
|
||||
const clientInfo = {
|
||||
authenticated: false,
|
||||
userId: null,
|
||||
adminName: null,
|
||||
currentPage: null,
|
||||
subscribedSessions: new Set(),
|
||||
lastPing: Date.now()
|
||||
};
|
||||
@@ -96,6 +98,15 @@ class WebSocketManager {
|
||||
clientInfo.lastPing = Date.now();
|
||||
this.send(ws, { type: 'pong' });
|
||||
break;
|
||||
|
||||
case 'page_focus':
|
||||
if (!clientInfo.authenticated) {
|
||||
this.sendError(ws, 'Not authenticated');
|
||||
return;
|
||||
}
|
||||
clientInfo.currentPage = message.page || null;
|
||||
this.broadcastPresence();
|
||||
break;
|
||||
|
||||
default:
|
||||
this.sendError(ws, `Unknown message type: ${message.type}`);
|
||||
@@ -117,7 +128,13 @@ class WebSocketManager {
|
||||
|
||||
if (clientInfo) {
|
||||
clientInfo.authenticated = true;
|
||||
clientInfo.userId = decoded.role; // 'admin' for now
|
||||
clientInfo.userId = decoded.role;
|
||||
clientInfo.adminName = decoded.name || null;
|
||||
|
||||
if (!decoded.name) {
|
||||
this.sendError(ws, 'Token missing admin identity, please re-login', 'auth_error');
|
||||
return;
|
||||
}
|
||||
|
||||
this.send(ws, {
|
||||
type: 'auth_success',
|
||||
@@ -283,9 +300,31 @@ class WebSocketManager {
|
||||
|
||||
this.clients.delete(ws);
|
||||
console.log('[WebSocket] Client disconnected and cleaned up');
|
||||
this.broadcastPresence();
|
||||
}
|
||||
}
|
||||
|
||||
broadcastPresence() {
|
||||
const admins = [];
|
||||
this.clients.forEach((info) => {
|
||||
if (info.authenticated && info.adminName && info.currentPage) {
|
||||
admins.push({ name: info.adminName, page: info.currentPage });
|
||||
}
|
||||
});
|
||||
|
||||
const message = {
|
||||
type: 'presence_update',
|
||||
timestamp: new Date().toISOString(),
|
||||
admins
|
||||
};
|
||||
|
||||
this.clients.forEach((info, ws) => {
|
||||
if (info.authenticated && ws.readyState === ws.OPEN) {
|
||||
this.send(ws, message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Start heartbeat to detect dead connections
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user