initial files

This commit is contained in:
2026-04-22 11:55:23 +02:00
commit 92444ff38c
85 changed files with 16324 additions and 0 deletions

View File

@@ -0,0 +1,336 @@
class SocketManager {
constructor(io) {
this.io = io;
this.namespaces = new Map();
this.clients = new Map();
this.io.on('connection', socket => {});
}
add(namespace, exists) {
if (this.namespaces.has(namespace)) return this.namespaces.get(namespace);
const nsp = this.io.of(namespace);
const clients = new Map();
this.clients.set(namespace, clients);
nsp.on('connection', socket => {
const { objectGuid, sAMAccountName } = socket.handshake.auth || {};
if (!objectGuid) return;
clients.set(objectGuid, {
socket,
userName: sAMAccountName
});
// console.log(`${sAMAccountName} [${objectGuid}] connected to ${namespace}`);
socket.on('disconnect', () => {
clients.delete(objectGuid);
// console.log(`${sAMAccountName} [${objectGuid}] disconnected from ${namespace}`);
});
});
this.namespaces.set(namespace, nsp);
return nsp;
}
async addAsync(namespace, exists) {
return new Promise(resolve => {
this.add(namespace, exists)
// simulierter async Init (z. B. DB)
setTimeout(resolve, 0);
});
}
/**
* Broadcast in namespace
* @param {string} namespace - Namespace-Name
* @param {string} event - Event-Name
* @param {any} data - Event-Data
*/
broadcast(namespace, event, data) {
const nsp = this.namespaces.get(namespace);
if (nsp) nsp.emit(event, data);
}
/**
* Event-Handler für einen Namespace registrieren
* @param {string} namespace - Namespace-Name
* @param {string} event - Event-Name
* @param {Function} callback - Callback mit (socket, data)
*/
// on(namespace, event, callback) {
// const nsp = this.namespaces.get(namespace);
// if (!nsp) {
// console.warn(`Namespace ${namespace} doesn't exist`);
// return;
// }
// nsp.on('connection', (socket) => {
// socket.on(event, (data) => {
// // übergibt socket als Kontext, damit sendTo automatisch weiß, wer anfragte
// callback(socket, data, (responseEvent, responseData, targetGuid = null) => {
// this.sendTo(namespace, targetGuid, responseEvent, responseData, socket);
// });
// });
// });
// }
on(namespace, event, callback) {
const nsp = this.namespaces.get(namespace);
if (!nsp) {
console.warn(`Namespace ${namespace} doesn't exist`);
return;
}
nsp.on('connection', (socket) => {
socket.on(event, (data) => callback(socket, data));
});
}
registerClient(namespace, socket) {
const nsp = this.namespaces.get(namespace);
if (!nsp) {
console.warn(`Namespace ${namespace} does not exist`);
return;
}
const auth = socket.handshake.auth;
const objectGuid = auth.objectGuid;
const sAMAccountName = auth.sAMAccountName;
if (!objectGuid) {
console.warn('Socket has no objectGuid, cannot register');
return;
}
socket.customId = objectGuid;
// In Map speichern
this.clients.set(objectGuid, {
userName: sAMAccountName,
socketId: socket.id,
socket: socket
});
console.log(`${sAMAccountName} [${objectGuid}] registered to namespace ${namespace}`);
// Disconnect-Handler
socket.on('disconnect', () => {
this.clients.delete(objectGuid);
console.log(`${sAMAccountName} [${objectGuid}] disconnected from namespace ${namespace}`);
});
};
/**
* Entfernt einen Client aus dem Namespace
* @param {string} objectGuid - GUID des Clients
* @param {string} [namespace] - optional, um Namespace-spezifisch zu loggen
*/
unregisterClient(objectGuid) {
try {
const client = this.clients.get(objectGuid);
if (!client) return;
// Optional: Socket trennen
client.socket.disconnect();
this.clients.delete(objectGuid);
const name = client.userName;
console.log(`${name} [${objectGuid}] manuell entfernt`);
} catch (err) {
console.log(err);
}
}
/**
* Send a personal message to ObjectGUID
* @param {string} namespace - Namespace-Name
* @param {string} objectGuid - Socket-ID
* @param {string} event - Event-Name
* @param {any} data - Event-Data
* @param {object} [senderSocket] - optionaler Absender-Socket
*/
sendTo(namespace, objectGuid, event, data, senderSocket = null) {
const clients = this.clients.get(namespace);
if (!clients) return;
// Antwort an Absender
if (!objectGuid && senderSocket) {
senderSocket.emit(event, data);
return;
}
const client = clients.get(objectGuid);
if (!client?.socket) return;
client.socket.emit(event, data);
}
}
module.exports = SocketManager;
// const WebSocket = require("ws");
// const url = require("url");
// class SocketManager {
// constructor() {
// this.namespaces = new Map(); // "/admin" → { clients:Set, handlers:Map }
// this.clients = new Map(); // objectGuid → { userName, socket }
// // Default-Namespaces wie bei Socket.IO
// this.add("/");
// this.add("/admin");
// }
// /**
// * Namespace erstellen
// */
// add(namespace) {
// if (this.namespaces.has(namespace)) return this.namespaces.get(namespace);
// const ns = {
// clients: new Set(),
// handlers: new Map() // event → callback
// };
// this.namespaces.set(namespace, ns);
// return ns;
// }
// /**
// * Upgrade (HTTP → WebSocket) pro Namespace auswerten
// */
// handleUpgrade(namespace, req, socket, head) {
// if (!this.namespaces.has(namespace)) {
// socket.destroy();
// return;
// }
// const ns = this.namespaces.get(namespace);
// const wss = new WebSocket.Server({ noServer: true });
// wss.handleUpgrade(req, socket, head, ws => {
// this._onConnection(namespace, ws, req);
// });
// }
// /**
// * Verbindung herstellen + authentifizieren
// */
// _onConnection(namespace, socket, req) {
// const params = new URLSearchParams(url.parse(req.url).query);
// const objectGuid = params.get("objectGuid");
// const sAMAccountName = params.get("sAMAccountName") || "Unknown";
// socket.namespace = namespace;
// socket.objectGuid = objectGuid;
// socket.userName = sAMAccountName;
// // Helper zum JSON-Senden
// socket.sendJSON = (obj) => socket.send(JSON.stringify(obj));
// const ns = this.namespaces.get(namespace);
// ns.clients.add(socket);
// if (objectGuid) {
// this.clients.set(objectGuid, { userName: sAMAccountName, socket: socket });
// console.log(`${sAMAccountName} [${objectGuid}] connected to [${namespace}]`);
// }
// // Nachrichten-Handling
// socket.on("message", raw => {
// let msg;
// try { msg = JSON.parse(raw); }
// catch { return; }
// const event = msg.event;
// const data = msg.data;
// const cb = ns.handlers.get(event);
// if (cb) cb(socket, data);
// });
// // Disconnect
// socket.on("close", () => {
// ns.clients.delete(socket);
// if (objectGuid) {
// this.clients.delete(objectGuid);
// console.log(`${sAMAccountName} [${objectGuid}] disconnected from namespace ${namespace}`);
// }
// });
// }
// /**
// * Events registrieren wie socket.on("event")
// */
// on(namespace, event, callback) {
// const ns = this.namespaces.get(namespace);
// if (!ns) return console.warn(`Namespace ${namespace} doesn't exist`);
// ns.handlers.set(event, callback);
// }
// /**
// * Broadcast in Namespace
// */
// broadcast(namespace, event, data) {
// const ns = this.namespaces.get(namespace);
// if (!ns) return;
// for (const client of ns.clients) {
// if (client.readyState === WebSocket.OPEN) {
// client.sendJSON({ event, data });
// }
// }
// }
// /**
// * Persönliche Nachricht an GUID
// */
// sendTo(namespace, objectGuid, event, data, sender = null) {
// if (!objectGuid && sender) {
// sender.sendJSON({ event, data });
// return;
// }
// const client = this.clients.get(objectGuid);
// if (!client) return;
// if (client.socket.readyState === WebSocket.OPEN) {
// client.socket.sendJSON({ event, data });
// }
// }
// /**
// * Client manuell entfernen
// */
// unregisterClient(objectGuid) {
// const client = this.clients.get(objectGuid);
// if (!client) return;
// client.socket.close(4000, "manual kick");
// this.clients.delete(objectGuid);
// console.log(`${client.userName} [${objectGuid}] manually removed`);
// }
// }
// module.exports = SocketManager;