Files
Luncher/server/src/websocket.ts
T
batmanisko 12fa87f3ad feat: Sentry monitoring a kompletnější sledování stavů Bolt Food
- integrace Sentry na serveru (@sentry/node) i klientu (@sentry/react):
  chyby 5xx, pády a console logy se hlásí do self-hosted Sentry
- nový veřejný endpoint GET /api/config — klient si z něj za běhu
  vyzvedne Sentry DSN (SENTRY_DSN / SENTRY_CLIENT_DSN v env)
- ErrorBoundary na klientu a sourcemapy pro čitelné stack traces
- oprava mapování stavu waiting_acceptance (zobrazoval se jako Příprava)
- mapování stavů kurýra matched/accepted, logování přechodů stavů
  Bolt objednávek pro postupné zmapování nedokumentovaného API
- simulátor Bolt ve vývoji nově prochází celou reálnou sekvenci stavů
- vypnuté logování connect/disconnect websocket klientů
2026-07-14 11:25:49 +02:00

58 lines
2.0 KiB
TypeScript

import { DefaultEventsMap, Server } from "socket.io";
import { createAdapter } from "@socket.io/redis-adapter";
import { createClient } from "redis";
let io: Server<DefaultEventsMap, DefaultEventsMap, DefaultEventsMap, any>;
let pubClient: ReturnType<typeof createClient>;
let subClient: ReturnType<typeof createClient>;
export const initWebsocket = (server: any) => {
io = new Server(server, {
cors: { origin: "*" },
transports: ["websocket"],
});
io.on("connection", (socket) => {
// console.log(`New client connected: ${socket.id}`);
socket.on("join", (login: string) => {
if (login && typeof login === "string") {
socket.join(`user:${login}`);
}
});
socket.on("message", (message) => {
io.emit("message", message);
});
socket.on("disconnect", () => {
// console.log(`Client disconnected: ${socket.id}`);
});
});
return io;
};
/** Připojí Redis adapter pro cross-pod broadcasting. Volat až po inicializaci Redis klienta. */
export const initRedisAdapter = async () => {
const HOST = process.env.REDIS_HOST ?? 'localhost';
const PORT = process.env.REDIS_PORT ?? 6379;
const url = `redis://${HOST}:${PORT}`;
pubClient = createClient({ url }) as ReturnType<typeof createClient>;
subClient = pubClient.duplicate();
await Promise.all([pubClient.connect(), subClient.connect()]);
io.adapter(createAdapter(pubClient as any, subClient as any));
console.log('Socket.io: Redis adapter connected');
};
/** Zavře pub/sub Redis klienty adaptéru při graceful shutdown. */
export const shutdownWebsocketClients = async () => {
await Promise.allSettled([pubClient?.quit(), subClient?.quit()]);
};
export const getWebsocket = () => io;
/** Pošle event konkrétnímu přihlášenému uživateli (pokud je připojen). */
export const emitToUser = (login: string, event: string, data: unknown) => {
if (!io) return;
io.to(`user:${login}`).emit(event, data);
};