contextProvider

This commit is contained in:
magdo
2025-11-18 00:09:08 +01:00
parent 13871b2dcc
commit 8647fde38f
7 changed files with 482 additions and 57 deletions
+4 -11
View File
@@ -14,6 +14,7 @@ import gameRouter from './routers/gameRouter';
import { LoggingService, logStartup, logConnection, logError, logRequest } from '../Application/Services/Logger';
import { WebSocketService } from '../Application/Services/WebSocketService';
import { GameWebSocketService } from '../Application/Services/GameWebSocketService';
import { container } from '../Application/Services/DIContainer';
import { GameRepository } from '../Infrastructure/Repository/GameRepository';
import { UserRepository } from '../Infrastructure/Repository/UserRepository';
import { RedisService } from '../Application/Services/RedisService';
@@ -183,17 +184,9 @@ AppDataSource.initialize()
chatInactivityTimeout: process.env.CHAT_INACTIVITY_TIMEOUT_MINUTES || '30'
});
// Initialize Game WebSocket service for /game namespace
const gameRepository = new GameRepository();
const userRepository = new UserRepository();
const redisService = RedisService.getInstance();
gameWebSocketService = new GameWebSocketService(
webSocketService['io'], // Access the io property directly
gameRepository,
userRepository,
redisService
);
// Initialize Game WebSocket service for /game namespace via DIContainer
container.setSocketIO(webSocketService['io']);
gameWebSocketService = container.gameWebSocketService;
logStartup('Game WebSocket service initialized for /game namespace');
})
.catch((error) => {
@@ -226,21 +226,43 @@ export class StartGamePlayCommandHandler {
private async notifyGameStart(game: GameAggregate): Promise<void> {
try {
// Note: WebSocket notifications will be handled when WebSocket service is available
// For now, just log the game start
logOther('Game start notifications prepared', {
// Get board data from Redis
const redisKey = `game_board_${game.id}`;
const boardDataStr = await this.redisService.get(redisKey);
if (!boardDataStr) {
logError('Board data not found in Redis during game start notification', new Error('Missing board data'));
return;
}
const boardData: BoardData = JSON.parse(boardDataStr);
// Get turn sequence from Redis
const gamePlayData = await this.getGamePlayFromRedis(game.id);
if (!gamePlayData) {
logError('Game play data not found in Redis', new Error('Missing game play data'));
return;
}
// Get WebSocket service from DIContainer and broadcast game start
const gameWebSocketService = DIContainer.getInstance().gameWebSocketService;
await gameWebSocketService.broadcastGameStart(
game.gamecode,
boardData,
gamePlayData.turnSequence,
game
);
logOther('Game start notifications sent via WebSocket', {
gameId: game.id,
gameCode: game.gamecode,
playerCount: game.players.length,
websocketRoom: `game_${game.gamecode}`
websocketRoom: `game_${game.gamecode}`,
firstPlayer: gamePlayData.turnSequence[0]
});
// TODO: Implement WebSocket notifications when service is properly integrated
// wsService.notifyGameStart(game.gamecode, game.players);
// wsService.broadcastGameStateUpdate(game.gamecode, gameStateData);
} catch (error) {
logError('Failed to prepare game start notifications', error instanceof Error ? error : new Error(String(error)));
logError('Failed to send game start notifications', error instanceof Error ? error : new Error(String(error)));
// Don't throw error here - notification failure shouldn't prevent game start
}
}
@@ -68,6 +68,8 @@ import { RedisService } from './RedisService';
import { GameService } from '../Game/GameService';
import { BoardGenerationService } from '../Game/BoardGenerationService';
import { GenerateBoardCommandHandler } from '../Game/commands/GenerateBoardCommandHandler';
import { GameWebSocketService } from './GameWebSocketService';
import type { Server as SocketIOServer } from 'socket.io';
/**
* Central Dependency Injection Container
@@ -96,6 +98,8 @@ export class DIContainer {
private _fieldEffectService: FieldEffectService | null = null;
private _gameService: GameService | null = null;
private _boardGenerationService: BoardGenerationService | null = null;
private _gameWebSocketService: GameWebSocketService | null = null;
private _socketIOInstance: SocketIOServer | null = null;
// Command Handlers
private _createUserCommandHandler: CreateUserCommandHandler | null = null;
@@ -272,6 +276,30 @@ export class DIContainer {
return this._boardGenerationService;
}
/**
* Set the Socket.IO instance (must be called before accessing gameWebSocketService)
*/
public setSocketIO(io: SocketIOServer): void {
this._socketIOInstance = io;
// Reset gameWebSocketService so it gets recreated with new IO instance
this._gameWebSocketService = null;
}
public get gameWebSocketService(): GameWebSocketService {
if (!this._gameWebSocketService) {
if (!this._socketIOInstance) {
throw new Error('Socket.IO instance must be set before accessing gameWebSocketService. Call setSocketIO() first.');
}
this._gameWebSocketService = new GameWebSocketService(
this._socketIOInstance,
this.gameRepository as any, // Cast to concrete type
this.userRepository as any, // Cast to concrete type
RedisService.getInstance()
);
}
return this._gameWebSocketService;
}
// Command Handler getters
public get createUserCommandHandler(): CreateUserCommandHandler {
if (!this._createUserCommandHandler) {