fix(api): use server.listen instead of app.listen for WebSocket support

- server.ts: switch from app.listen() to server.listen() so WebSocket
  upgrade handler is on the same server as HTTP requests
- lobbyService: add host as first player on lobby creation
- ws-client: guard against reconnect when already connecting
- ws-provider: skip connect if already connected
This commit is contained in:
lila 2026-04-18 21:57:58 +02:00
parent 974646ebfb
commit 540155788a
4 changed files with 14 additions and 2 deletions

View file

@ -9,6 +9,6 @@ const server = createServer(app);
setupWebSocket(server);
app.listen(PORT, () => {
server.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});

View file

@ -28,7 +28,9 @@ export const createLobby = async (hostUserId: string): Promise<Lobby> => {
for (let i = 0; i < MAX_CODE_ATTEMPTS; i++) {
const code = generateLobbyCode();
try {
return await createLobbyModel(code, hostUserId);
const lobby = await createLobbyModel(code, hostUserId);
await addPlayer(lobby.id, hostUserId, MAX_LOBBY_PLAYERS);
return lobby;
} catch (err) {
if (isUniqueViolation(err)) continue;
throw err;

View file

@ -25,6 +25,14 @@ export class WsClient {
public onClose: ((event: CloseEvent) => void) | null = null;
connect(apiUrl: string): Promise<void> {
// If already connected or connecting, resolve immediately
if (
this.ws &&
(this.ws.readyState === WebSocket.OPEN ||
this.ws.readyState === WebSocket.CONNECTING)
) {
return Promise.resolve();
}
return new Promise((resolve, reject) => {
if (this.ws) {
this.ws.close();

View file

@ -9,6 +9,8 @@ export const WsProvider = ({ children }: { children: ReactNode }) => {
const [isConnected, setIsConnected] = useState(false);
const connect = useCallback(async (url: string): Promise<void> => {
if (wsClient.isConnected()) return;
wsClient.onClose = () => setIsConnected(false);
wsClient.onError = () => setIsConnected(false);
try {