Files
NowChess-Frontend/src/app/services/challenge-websocket.service.ts
T
shosho996 bad7366bdb feat: NCS-69 Challenge request (#3)
- create challange window
- challanges view page
- decline and accept
- notif tab (wip)
- active game window (wip)

---------

Co-authored-by: shahdlala66 <shahd.lala66@gmail.com>
Co-authored-by: Lala, Shahd <Shahd.Lala@sybit.de>
Reviewed-on: #3
2026-05-12 22:38:57 +02:00

136 lines
4.1 KiB
TypeScript

import { Injectable, inject } from '@angular/core';
import { Subject } from 'rxjs';
import { ChallengeEventService } from './challenge-event.service';
import { Challenge } from '../models/challenge.models';
/**
* Service to handle WebSocket connections for challenge events
* Listens for incoming challenge notifications and emits them to ChallengeEventService
*/
@Injectable({ providedIn: 'root' })
export class ChallengeWebSocketService {
private readonly challengeEventService = inject(ChallengeEventService);
private ws: WebSocket | null = null;
private reconnectAttempts = 0;
private readonly maxReconnectAttempts = 5;
private readonly reconnectDelay = 3000;
/**
* Initialize WebSocket connection for challenge events
*/
connect(): void {
if (this.ws) {
return; // Already connected
}
const wsProtocol = window.location.protocol === 'https:' ? 'wss' : 'ws';
const wsUrl = `${wsProtocol}://${window.location.host}/ws/challenges`;
try {
this.ws = new WebSocket(wsUrl);
this.ws.onopen = () => {
console.log('Challenge WebSocket connected');
this.reconnectAttempts = 0;
};
this.ws.onmessage = (event) => {
this.handleMessage(event.data);
};
this.ws.onerror = (error) => {
console.error('Challenge WebSocket error:', error);
};
this.ws.onclose = () => {
console.log('Challenge WebSocket disconnected');
this.ws = null;
this.attemptReconnect();
};
} catch (error) {
console.error('Failed to create WebSocket:', error);
this.attemptReconnect();
}
}
/**
* Close the WebSocket connection
*/
disconnect(): void {
if (this.ws) {
this.ws.close();
this.ws = null;
}
}
/**
* Send a message through WebSocket
*/
send(message: any): void {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify(message));
}
}
/**
* Handle incoming WebSocket messages
*/
private handleMessage(data: string): void {
try {
const message = JSON.parse(data);
if (!message.type) {
return;
}
switch (message.type) {
case 'challenge.received':
if (message.challenge) {
this.challengeEventService.onChallengeReceived(message.challenge as Challenge);
}
break;
case 'challenge.accepted':
if (message.challenge) {
this.challengeEventService.onChallengeAccepted(message.challenge as Challenge);
}
break;
case 'challenge.declined':
if (message.challengeId) {
this.challengeEventService.removeChallenge(message.challengeId);
}
break;
case 'challenge.expired':
if (message.challengeId) {
this.challengeEventService.removeChallenge(message.challengeId);
}
break;
default:
console.debug('Unknown challenge message type:', message.type);
}
} catch (error) {
console.error('Failed to parse WebSocket message:', error);
}
}
/**
* Attempt to reconnect to WebSocket
*/
private attemptReconnect(): void {
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
console.error('Max WebSocket reconnection attempts reached');
return;
}
this.reconnectAttempts++;
console.log(`Attempting WebSocket reconnect (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
setTimeout(() => {
this.connect();
}, this.reconnectDelay);
}
}