Files
SHiNE-server/SHiNE-server/src/main/java/server/ws/WsServer.java
T

112 lines
5.2 KiB
Java

package server.ws;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import server.debug.DebugApiConfigurator;
import server.sync.BlockchainResyncRecoveryOnStartup;
import server.sync.PeriodicBlockchainSyncService;
import server.sync.PeriodicDmSyncService;
import server.sync.PeriodicUserSettingsSyncService;
import server.sync.SolanaUsersSyncStartupService;
import server.sync.SyncServersBootstrapService;
import utils.config.AppConfig;
import java.time.Duration;
/**
* WsServer — поднимает Jetty WS на /ws.
*
* ВАЖНО:
* - перед стартом сервера выполняем recovery tmp-блокчейнов.
* - если обнаружена несогласованность, которую сервер сам чинить не может —
* recovery бросает исключение и сервер не стартует.
*/
public final class WsServer {
private static final Logger log = LoggerFactory.getLogger(WsServer.class);
public static void main(String[] args) throws Exception {
// ============================================================
// 0) Восстановление консистентности blockchain файлов
// ============================================================
try {
BlockchainTmpRecoveryOnStartup.runRecoveryOrThrow();
} catch (Exception e) {
// Уже должно быть “большое” уведомление через BlockchainAdminNotifier,
// но на всякий случай логируем ещё раз.
log.error("❌ Сервер НЕ будет запущен: критическая ошибка восстановления blockchain tmp-файлов.", e);
throw e; // останавливаем запуск
}
// ============================================================
// 0.1) Восстановление цепочек, зависших на full resync
// ============================================================
try {
BlockchainResyncRecoveryOnStartup.runRecoveryOrThrow();
} catch (Exception e) {
log.error("❌ Сервер НЕ будет запущен: критическая ошибка восстановления blockchain resync-маркеров.", e);
throw e;
}
// ============================================================
// 1.0) Синхронизация пользовательских Solana PDA
// ============================================================
SolanaUsersSyncStartupService.startOrThrow();
// ============================================================
// 1) Настройки порта
// ============================================================
AppConfig config = AppConfig.getInstance();
int port = 7070;
try {
String portStr = config.getParam("server.port");
if (portStr != null && !portStr.isBlank()) {
port = Integer.parseInt(portStr.trim());
}
} catch (Exception e) {
log.info("Не удалось прочитать параметр server.port, используем порт по умолчанию {}", port);
}
// ============================================================
// 1.1) Загрузка списка серверов синхронизации из Solana PDA
// ============================================================
SyncServersBootstrapService.refreshFromSolanaOrLog();
// ============================================================
// 1.2) Плановый межсерверный sync блокчейнов
// ============================================================
PeriodicBlockchainSyncService.startOrLog();
// ============================================================
// 2) Запуск Jetty WS
// ============================================================
Server server = new Server(port);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
server.setHandler(context);
// HTTP debug API
DebugApiConfigurator.register(context);
// Инициализация контейнера WebSocket
JettyWebSocketServletContainerInitializer.configure(context, (servletContext, wsContainer) -> {
// Таймаут простоя соединения (Jetty 11 синтаксис)
wsContainer.setIdleTimeout(Duration.ofMinutes(5));
// Маппинг эндпоинта
wsContainer.addMapping("/ws", (req, resp) -> new BlockchainWsEndpoint());
});
server.start();
log.info("✅ WS сервер запущен на ws://localhost:{}/ws", port);
PeriodicDmSyncService.startOrLog();
PeriodicUserSettingsSyncService.startOrLog();
server.join();
}
}