import { DockgeSocket } from "./util-server"; import { io, Socket as SocketClient } from "socket.io-client"; import { log } from "./log"; import { Agent } from "./models/agent"; import { LooseObject } from "../common/util-common"; /** * Dockge Instance Manager */ export class AgentManager { protected socket : DockgeSocket; protected instanceSocketList : Record = {}; constructor(socket: DockgeSocket) { this.socket = socket; } connect(url : string, username : string, password : string) { let obj = new URL(url); let endpoint = obj.host; this.socket.emit("agentStatus", { endpoint: endpoint, status: "connecting", }); if (!endpoint) { log.error("agent-manager", "Invalid endpoint: " + endpoint + " URL: " + url); return; } if (this.instanceSocketList[endpoint]) { log.debug("agent-manager", "Already connected to the socket server: " + endpoint); return; } log.info("agent-manager", "Connecting to the socket server: " + endpoint); let client = io(url, { extraHeaders: { endpoint, } }); client.on("connect", () => { log.info("agent-manager", "Connected to the socket server: " + endpoint); client.emit("login", { username: username, password: password, }, (res) => { if (res.ok) { log.info("agent-manager", "Logged in to the socket server: " + endpoint); this.socket.emit("agentStatus", { endpoint: endpoint, status: "online", }); } else { log.error("agent-manager", "Failed to login to the socket server: " + endpoint); this.socket.emit("agentStatus", { endpoint: endpoint, status: "offline", }); } }); }); client.on("error", (err) => { log.error("agent-manager", "Error from the socket server: " + endpoint); log.error("agent-manager", err); this.socket.emit("agentStatus", { endpoint: endpoint, status: "offline", }); }); client.on("disconnect", () => { log.info("agent-manager", "Disconnected from the socket server: " + endpoint); this.socket.emit("agentStatus", { endpoint: endpoint, status: "offline", }); }); client.on("agent", (...args : unknown[]) => { log.debug("agent-manager", "Forward event"); this.socket.emit("agent", ...args); }); this.instanceSocketList[endpoint] = client; } disconnect(endpoint : string) { let client = this.instanceSocketList[endpoint]; client?.disconnect(); } async connectAll() { if (this.socket.endpoint) { log.info("agent-manager", "This connection is connected as an agent, skip connectAll()"); return; } let list : Record = await Agent.getAgentList(); if (Object.keys(list).length !== 0) { log.info("agent-manager", "Connecting to all instance socket server(s)..."); } for (let endpoint in list) { let agent = list[endpoint]; this.connect(agent.url, agent.username, agent.password); } } disconnectAll() { for (let endpoint in this.instanceSocketList) { this.disconnect(endpoint); } } emitToEndpoint(endpoint: string, eventName: string, ...args : unknown[]) { log.debug("agent-manager", "Emitting event to endpoint: " + endpoint); let client = this.instanceSocketList[endpoint]; if (!client) { log.error("agent-manager", "Socket client not found for endpoint: " + endpoint); throw new Error("Socket client not found for endpoint: " + endpoint); } client?.emit("agent", endpoint, eventName, ...args); } emitToAllEndpoints(eventName: string, ...args : unknown[]) { log.debug("agent-manager", "Emitting event to all endpoints"); for (let endpoint in this.instanceSocketList) { this.emitToEndpoint(endpoint, eventName, ...args); } } async sendAgentList() { let list = await Agent.getAgentList(); let result : Record = {}; // Myself result[""] = { url: "", username: "", endpoint: "", }; for (let endpoint in list) { let agent = list[endpoint]; result[endpoint] = agent.toJSON(); } this.socket.emit("agentList", { ok: true, agentList: result, }); } }