AeThex-OS/server/websocket.ts
MrPiglr 106253255a modified: server/openai.ts
modified:   server/websocket.ts
2025-12-23 21:41:48 +00:00

225 lines
6.4 KiB
TypeScript

import { Server } from "http";
import { Server as SocketIOServer, Socket } from "socket.io";
import { storage } from "./storage.js";
interface SocketData {
userId?: string;
isAdmin?: boolean;
}
export function setupWebSocket(httpServer: Server) {
const io = new SocketIOServer(httpServer, {
cors: {
origin: "*",
methods: ["GET", "POST"],
},
path: "/socket.io"
});
io.on("connection", async (socket: Socket) => {
console.log("Socket.IO client connected:", socket.id);
// Send initial connection message
socket.emit("connected", {
message: "AeThex OS WebSocket connected",
timestamp: new Date().toISOString()
});
// Handle authentication
socket.on("auth", async (data: { userId: string; isAdmin?: boolean }) => {
const socketData = socket.data as SocketData;
socketData.userId = data.userId;
socketData.isAdmin = data.isAdmin || false;
socket.emit("auth_success", {
userId: data.userId,
timestamp: new Date().toISOString()
});
// Join user-specific room
socket.join(`user:${data.userId}`);
if (data.isAdmin) {
socket.join("admins");
}
// Send initial data after auth
await sendInitialData(socket, socketData);
});
// Send initial notifications and alerts
try {
const [metrics, alerts, achievements] = await Promise.all([
storage.getMetrics(),
storage.getAlerts(),
storage.getAchievements()
]);
socket.emit("metrics", metrics);
socket.emit("alerts", alerts.filter(a => !a.is_resolved).slice(0, 5));
socket.emit("achievements", achievements.slice(0, 10));
} catch (error) {
console.error("Error sending initial data:", error);
}
// Listen for alert resolution events
socket.on("resolveAlert", async (alertId: string) => {
try {
await storage.updateAlert(alertId, { is_resolved: true, resolved_at: new Date() });
const alerts = await storage.getAlerts();
io.to("admins").emit("alerts", alerts.filter(a => !a.is_resolved));
io.to("admins").emit("alert_resolved", { alertId, timestamp: new Date().toISOString() });
} catch (error) {
console.error("Error resolving alert:", error);
socket.emit("error", { message: "Failed to resolve alert" });
}
});
// Listen for request to refresh notifications
socket.on("refreshNotifications", async () => {
try {
const metrics = await storage.getMetrics();
socket.emit("notifications", [
{ id: 1, message: `${metrics.totalProfiles} architects in network`, type: 'info' },
{ id: 2, message: `${metrics.totalProjects} active projects`, type: 'info' },
{ id: 3, message: 'Aegis security active', type: 'success' }
]);
} catch (error) {
console.error("Error refreshing notifications:", error);
}
});
// Listen for metrics refresh
socket.on("refreshMetrics", async () => {
try {
const metrics = await storage.getMetrics();
socket.emit("metrics", metrics);
} catch (error) {
console.error("Error refreshing metrics:", error);
}
});
// Listen for achievements refresh
socket.on("refreshAchievements", async () => {
try {
const achievements = await storage.getAchievements();
socket.emit("achievements", achievements);
} catch (error) {
console.error("Error refreshing achievements:", error);
}
});
socket.on("disconnect", () => {
console.log("Socket.IO client disconnected:", socket.id);
});
});
// Start periodic updates
startPeriodicUpdates(io);
return io;
}
async function sendInitialData(socket: Socket, socketData: SocketData) {
try {
// Send recent alerts if admin
if (socketData.isAdmin) {
const alerts = await storage.getAlerts();
const unresolved = alerts.filter(a => !a.is_resolved).slice(0, 5);
socket.emit("admin_alerts", unresolved);
}
// Send metrics
const metrics = await storage.getMetrics();
socket.emit("metrics_update", metrics);
// Send recent achievements
const achievements = await storage.getAchievements();
socket.emit("achievements_update", achievements.slice(0, 10));
} catch (error) {
console.error("Error sending initial data:", error);
}
}
function startPeriodicUpdates(io: SocketIOServer) {
// Send metrics updates every 30 seconds
setInterval(async () => {
try {
const metrics = await storage.getMetrics();
io.emit("metrics_update", metrics);
} catch (error) {
console.error("Error broadcasting metrics:", error);
}
}, 30000);
// Check for new alerts every 10 seconds
let lastAlertCheck = new Date();
setInterval(async () => {
try {
const alerts = await storage.getAlerts();
const newAlerts = alerts.filter(a =>
!a.is_resolved &&
a.created_at && !isNaN(new Date(a.created_at).getTime()) && new Date(a.created_at) > lastAlertCheck
);
if (newAlerts.length > 0) {
io.to("admins").emit("new_alerts", {
alerts: newAlerts,
count: newAlerts.length,
timestamp: new Date().toISOString()
});
}
lastAlertCheck = new Date();
} catch (error) {
console.error("Error broadcasting alerts:", error);
}
}, 10000);
}
// Export helper functions for triggering broadcasts
export const websocket = {
io: null as SocketIOServer | null,
setIO(ioInstance: SocketIOServer) {
this.io = ioInstance;
},
// Helper to notify about new achievements
notifyAchievement(userId: string, achievement: any) {
if (this.io) {
this.io.to(`user:${userId}`).emit("achievement_unlocked", {
data: achievement,
timestamp: new Date().toISOString()
});
}
},
// Helper to notify about new alerts
notifyAlert(alert: any) {
if (this.io) {
this.io.to("admins").emit("alert", {
data: alert,
timestamp: new Date().toISOString()
});
}
},
// Helper to notify about system events
notifySystem(message: string, severity: "info" | "warning" | "error" = "info") {
if (this.io) {
this.io.emit("system_notification", {
message,
severity,
timestamp: new Date().toISOString()
});
}
},
// Broadcast to all clients
broadcast(event: string, data: any) {
if (this.io) {
this.io.emit(event, data);
}
}
};