88 lines
2.2 KiB
JavaScript
88 lines
2.2 KiB
JavaScript
import { SocketClient } from "./SocketClient.js";
|
|
import { SubscriptionRegistry } from "./SubscriptionRegistry.js";
|
|
|
|
export class SocketManager {
|
|
/**
|
|
* @param {import("socket.io").Server} io
|
|
* @param {object} [options]
|
|
* @param {SubscriptionRegistry} [options.subscriptionRegistry]
|
|
*/
|
|
constructor(io, options = {}) {
|
|
this.io = io;
|
|
this.subscriptionRegistry =
|
|
options.subscriptionRegistry ?? new SubscriptionRegistry();
|
|
this.clients = new Map();
|
|
/** @type {((socket: import("socket.io").Socket, client: SocketClient) => void) | null} */
|
|
this.registerSocketApi = null;
|
|
this.setup();
|
|
}
|
|
|
|
setup() {
|
|
this.io.on("connection", (socket) => this.handleConnection(socket));
|
|
}
|
|
|
|
handleConnection(socket) {
|
|
const client = new SocketClient(socket);
|
|
client.onDisconnect = (c) => {
|
|
this.subscriptionRegistry.removeSocket(c.id);
|
|
this.clients.delete(c.id);
|
|
};
|
|
client.setupListeners();
|
|
if (this.registerSocketApi) {
|
|
this.registerSocketApi(socket, client);
|
|
}
|
|
this.clients.set(socket.id, client);
|
|
}
|
|
|
|
/**
|
|
* Broadcast { type, payload } to all clients (legacy / non-subscription paths).
|
|
*/
|
|
broadcast(data) {
|
|
if (data && data.type !== undefined) {
|
|
this.io.emit(data.type, data.payload);
|
|
} else {
|
|
this.io.emit("message", data);
|
|
}
|
|
}
|
|
|
|
emitToSubscribers(channelKey, event, payload) {
|
|
const ids = this.subscriptionRegistry.getSubscriberIds(channelKey);
|
|
for (const socketId of ids) {
|
|
this.io.to(socketId).emit(event, payload);
|
|
}
|
|
}
|
|
|
|
emitPatchUpdated(patch) {
|
|
if (!patch?.id) return;
|
|
this.emitToSubscribers(`patch:${patch.id}`, "patchUpdated", { patch });
|
|
}
|
|
|
|
emitWaterTankUpdated(payload) {
|
|
this.emitToSubscribers("waterTank", "waterTankUpdated", payload);
|
|
}
|
|
|
|
emitPowerUpdated(payload) {
|
|
this.emitToSubscribers("power", "powerUpdated", payload);
|
|
}
|
|
|
|
emitWateringSessionsUpdated(payload) {
|
|
this.emitToSubscribers(
|
|
"wateringSessions",
|
|
"wateringSessionsUpdated",
|
|
payload,
|
|
);
|
|
}
|
|
|
|
emitWaterSchedulesUpdated(payload) {
|
|
this.emitToSubscribers(
|
|
"waterSchedules",
|
|
"waterSchedulesUpdated",
|
|
payload,
|
|
);
|
|
}
|
|
|
|
getClient(id) {
|
|
return this.clients.get(id);
|
|
}
|
|
}
|