websocket stuff

This commit is contained in:
Darius
2026-02-06 11:15:11 +01:00
parent 5866216e36
commit b9a494a87c
4 changed files with 2142 additions and 2170 deletions

4262
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,9 +2,8 @@ import {
BaseService, BaseService,
FullInformation, FullInformation,
HomeAssistantDeskPositionResult, HomeAssistantDeskPositionResult,
SseClientChangeEvent,
SseService,
TidalGetCurrent, TidalGetCurrent,
WsService,
type ServiceResult, type ServiceResult,
} from "@dpu/shared"; } from "@dpu/shared";
import { logInfo, logWarning } from "@dpu/shared/dist/logger.js"; import { logInfo, logWarning } from "@dpu/shared/dist/logger.js";
@@ -14,19 +13,19 @@ import { TidalService } from "../tidal/service";
export class HomepageService extends BaseService<null> { export class HomepageService extends BaseService<null> {
private haService: HomeAssistantService; private haService: HomeAssistantService;
private tidalService: TidalService; private tidalService: TidalService;
private sseService: SseService; private wsService: WsService;
private pollingInterval: ReturnType<typeof setInterval> | null = null; private pollingInterval: ReturnType<typeof setInterval> | null = null;
private lastPoll: FullInformation | null = null; private lastPoll: FullInformation | null = null;
constructor( constructor(
haService: HomeAssistantService, haService: HomeAssistantService,
tidalService: TidalService, tidalService: TidalService,
sseService: SseService, wsService: WsService,
) { ) {
super(null); super(null);
this.haService = haService; this.haService = haService;
this.tidalService = tidalService; this.tidalService = tidalService;
this.sseService = sseService; this.wsService = wsService;
this.listenForClientChange(); this.listenForClientChange();
} }
@@ -87,7 +86,7 @@ export class HomepageService extends BaseService<null> {
if (updates.length > 0) { if (updates.length > 0) {
logInfo("Updating clients"); logInfo("Updating clients");
this.sseService.notifyClients({ this.wsService.broadcast({
type: "update", type: "update",
data: updates, data: updates,
}); });
@@ -98,8 +97,8 @@ export class HomepageService extends BaseService<null> {
} }
listenForClientChange(): void { listenForClientChange(): void {
this.sseService.onClientChange((clientChange: SseClientChangeEvent) => { this.wsService.onClientChange((clients: number) => {
if (clientChange.clientCount === 0) { if (clients === 0) {
this.stopPolling(); this.stopPolling();
} else { } else {
if (!this.pollingInterval) { if (!this.pollingInterval) {

View File

@@ -19,12 +19,12 @@ import { HomeAssistantService } from "./homeassistant/service.js";
import { TidalClient } from "./tidal/client.js"; import { TidalClient } from "./tidal/client.js";
import { TidalService } from "./tidal/service.js"; import { TidalService } from "./tidal/service.js";
import { tidalRoutes } from "./tidal/routes.js"; import { tidalRoutes } from "./tidal/routes.js";
import { sseRoutes } from "./websocket/routes.js"; import { wsRoutes } from "./websocket/routes.js";
import { SseService } from "@dpu/shared";
import { HomepageService } from "./homepage/service.js"; import { HomepageService } from "./homepage/service.js";
import { homepageRoutes } from "./homepage/routes.js"; import { homepageRoutes } from "./homepage/routes.js";
import fastifyCors from "@fastify/cors"; import fastifyCors from "@fastify/cors";
import fastifyWebsocket from "@fastify/websocket"; import fastifyWebsocket from "@fastify/websocket";
import { WsService } from "@dpu/shared";
const fastify = Fastify().withTypeProvider<ZodTypeProvider>(); const fastify = Fastify().withTypeProvider<ZodTypeProvider>();
@@ -89,9 +89,9 @@ const haService = new HomeAssistantService(haClient);
const tidalClient = new TidalClient(fastify.axios.tidal); const tidalClient = new TidalClient(fastify.axios.tidal);
const tidalService = new TidalService(tidalClient); const tidalService = new TidalService(tidalClient);
const sseService = new SseService(); const wsService = new WsService();
const hpService = new HomepageService(haService, tidalService, sseService); const hpService = new HomepageService(haService, tidalService, wsService);
async function verifyAPIKey( async function verifyAPIKey(
request: FastifyRequest, request: FastifyRequest,
@@ -110,7 +110,7 @@ const port = parseInt(Config.port, 10);
// Register routes // Register routes
await fastify.register(homeAssistantRoutes, { haService, verifyAPIKey }); await fastify.register(homeAssistantRoutes, { haService, verifyAPIKey });
await fastify.register(tidalRoutes, { tidalService, verifyAPIKey }); await fastify.register(tidalRoutes, { tidalService, verifyAPIKey });
await fastify.register(sseRoutes, { sseService }); await fastify.register(wsRoutes, { wsService });
await fastify.register(homepageRoutes, { hpService }); await fastify.register(homepageRoutes, { hpService });
fastify.get( fastify.get(

View File

@@ -1,13 +1,12 @@
import type { FastifyInstance } from "fastify"; import type { FastifyInstance } from "fastify";
import { logInfo, type SseEvent, type SseService } from "@dpu/shared"; import { logInfo, WsService } from "@dpu/shared";
import { randomUUID } from "node:crypto";
export async function sseRoutes( export async function wsRoutes(
fastify: FastifyInstance, fastify: FastifyInstance,
{ {
sseService, wsService,
}: { }: {
sseService: SseService; wsService: WsService;
}, },
) { ) {
fastify.get( fastify.get(
@@ -21,21 +20,13 @@ export async function sseRoutes(
websocket: true, websocket: true,
}, },
(socket, _request) => { (socket, _request) => {
const clientId = randomUUID(); wsService.addClient(socket);
const sendEvent = (event: SseEvent) => {
if (socket.readyState === socket.OPEN) {
socket.send(JSON.stringify({ event: event.type, data: event.data }));
}
};
sseService.addClient({ id: clientId, send: sendEvent });
socket.send(JSON.stringify({ event: "connected", data: "Connected" })); socket.send(JSON.stringify({ event: "connected", data: "Connected" }));
logInfo(`Connection for client ${clientId} established`); logInfo(`Connection for client established`);
socket.on("close", () => { socket.on("close", () => {
sseService.removeClient(clientId); wsService.removeClient(socket);
logInfo(`Connection for client ${clientId} closed`); logInfo(`Connection for client closed`);
}); });
}, },
); );