Server (@nerdware/server): - RoomManager: in-memory rooms (Map), code generation, create/join, disconnect handling, public snapshot projection (no secrets) - Socket.IO handlers: room:create / room:join with typed acks, room:state broadcast on every change, lobby:updateSettings (host-only), player:left on disconnect Web (web): - typed Socket.IO client + Zustand store mirroring room:state - wouter routing: home (create/join) + minimal lobby (live player list) - @nerdware/shared wired into the client Roadmap V1 step 2. Verified end-to-end (create/join/broadcast/disconnect). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
41 lines
1.1 KiB
TypeScript
41 lines
1.1 KiB
TypeScript
import type { Server as HttpServer } from "node:http"
|
|
import { Server } from "socket.io"
|
|
import type {
|
|
ClientToServerEvents,
|
|
InterServerEvents,
|
|
ServerToClientEvents,
|
|
SocketData,
|
|
} from "@nerdware/shared"
|
|
import { env } from "./env"
|
|
import { registerRoomHandlers } from "./handlers"
|
|
import { RoomManager } from "./rooms"
|
|
|
|
/** Serveur Socket.IO entièrement typé via les events partagés. */
|
|
export type IoServer = Server<
|
|
ClientToServerEvents,
|
|
ServerToClientEvents,
|
|
InterServerEvents,
|
|
SocketData
|
|
>
|
|
|
|
/** Crée et attache le serveur Socket.IO au serveur HTTP de Fastify. */
|
|
export function createSocketServer(httpServer: HttpServer): IoServer {
|
|
const io: IoServer = new Server(httpServer, {
|
|
cors: {
|
|
origin: env.corsOrigins,
|
|
methods: ["GET", "POST"],
|
|
},
|
|
})
|
|
|
|
const rooms = new RoomManager()
|
|
|
|
io.on("connection", (socket) => {
|
|
console.log(`[ws] connect ${socket.id}`)
|
|
registerRoomHandlers(io, socket, rooms)
|
|
socket.on("disconnect", (reason) => {
|
|
console.log(`[ws] disconnect ${socket.id} (${reason})`)
|
|
})
|
|
})
|
|
|
|
return io
|
|
}
|