-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
124 lines (105 loc) · 5.15 KB
/
Copy pathProgram.cs
File metadata and controls
124 lines (105 loc) · 5.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
using System;
using System.Threading;
using System.Threading.Tasks;
using WebSocketServer.Configuration;
using WebSocketServer.Network;
using WebSocketServer.Persistence;
using WebSocketServer.Protocol.Serialization;
using WebSocketServer.Services;
using WebSocketServer.Services.Handlers;
namespace WebSocketServer;
/// <summary>
/// Punto de entrada principal (Composition Root) para el servidor de videojuegos multijugador con WebSockets nativos.
/// </summary>
public static class Program
{
/// <summary>
/// Método de inicio asíncrono que orquesta la inicialización de la base de datos,
/// inyección de dependencias y arranque del listener de red.
/// </summary>
/// <param name="args">Argumentos de la línea de comandos.</param>
/// <returns>Tarea que representa el ciclo de vida completo de ejecución del servidor.</returns>
public static async Task Main(string[] args)
{
try
{
Console.Title = "Game Server - Native .NET WebSocket & SQLite WAL";
}
catch
{
// Ignorar en entornos headless o contenedores donde Console.Title no está soportado
}
PrintBanner();
// 1. Cargar Configuración Operativa
var config = new ServerConfig();
// 2. Inicialización de la Base de Datos Ultraligera SQLite en modo WAL
Console.WriteLine("[Base de Datos] Inicializando motor SQLite...");
var dbConnectionFactory = new DatabaseConnectionFactory(config);
var dbInitializer = new DatabaseInitializer(dbConnectionFactory);
await dbInitializer.InitializeAsync();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("[Base de Datos] SQLite WAL inicializado y optimizado con éxito.");
Console.ResetColor();
// 3. Inicialización de Capa de Persistencia y Repositorios
var userRepository = new SqliteUserRepository(dbConnectionFactory);
var chatRepository = new SqliteChatRepository(dbConnectionFactory);
// 4. Capa de Protocolo y Serialización
var serializer = JsonNetworkSerializer.Instance;
// 5. Capa de Red y Gestión de Sesiones
var connectionManager = new ConnectionManager();
var packetRouter = new PacketRouter(serializer);
// 6. Capa de Lógica de Negocio y Servicios de Dominio
var userService = new UserService(userRepository, connectionManager, serializer);
var chatService = new ChatService(chatRepository, connectionManager, serializer);
// 7. Registro Desacoplado de Manejadores de Paquetes (SRP)
packetRouter.RegisterHandler(new AuthPacketHandler(userService, chatService, serializer));
packetRouter.RegisterHandler(new PositionPacketHandler(userService, connectionManager, serializer));
packetRouter.RegisterHandler(new ChatPacketHandler(chatService, serializer));
// 8. Inicialización del Listener de Red WebSocket
using var listener = new ServerWebSocketListener(config, connectionManager, packetRouter);
listener.ClientConnected += (session) =>
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine($"[Red] [+] Cliente conectado. Sesión: {session.SessionId} | Activas: {connectionManager.ActiveConnectionsCount}");
Console.ResetColor();
};
listener.ClientDisconnected += (session) =>
{
Console.ForegroundColor = ConsoleColor.DarkGray;
string username = session.AuthenticatedUser?.Username ?? "Anónimo";
Console.WriteLine($"[Red] [-] Cliente desconectado. Sesión: {session.SessionId} ({username}) | Activas: {connectionManager.ActiveConnectionsCount}");
Console.ResetColor();
_ = userService.NotifyUserLeftAsync(session);
};
listener.Start();
// Manejo de apagado ordenado mediante Ctrl+C
var exitEvent = new ManualResetEventSlim(false);
Console.CancelKeyPress += (sender, eventArgs) =>
{
eventArgs.Cancel = true;
Console.WriteLine("\n[Servidor] Señal de terminación recibida. Cerrando ordenadamente...");
exitEvent.Set();
};
Console.WriteLine("\n[Servidor] Listo y esperando conexiones de clientes Unity.");
Console.WriteLine("[Servidor] Presiona Ctrl+C para detener el servidor.\n");
exitEvent.Wait();
Console.WriteLine("[Servidor] Deteniendo listener de red...");
await listener.StopAsync();
Console.WriteLine("[Servidor] Apagado completo.");
}
private static void PrintBanner()
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine(@"
===================================================================
SERVIDOR DE VIDEOJUEGO MULTIJUGADOR (.NET WEBSOCKET)
===================================================================
Arquitectura: Clean Architecture & Modular Layering
Protocolo : JSON Envelopes sobre WebSockets nativos
Base Datos : SQLite nativa en modo WAL ultraligero
Conectividad: Unity 3D Ready (Assets/Scripts/Networking/)
===================================================================
");
Console.ResetColor();
}
}