@@ -1070,6 +1070,93 @@ export * from "./core-v2.js"; // v1 -> v2 로 숫자 하나만 바꿨습니다.
10701070> 3. ** 임포트 체크** : 상단에 있는 ` narrate` 함수가 정확한 경로(` ../narrator.js` )에서 오고 있는지 확인하세요. (ESM 방식이므로 ` .js` 확장자를 붙이는 것이 포인트입니다! )
10711071
10721072
1073+ # ### 2-8-0. [실제 완성 코드] `src/gateway/server.impl.ts` (핵심 엔진)
1074+
1075+ 이 코드는 OpenClaw 시스템의 모든 부품을 조립하는 ** 최종 설계도** 입니다. 500줄이 넘는 방대한 양이지만, 핵심이 되는 ` startGatewayServer` 함수의 내부 로직을 상세히 파헤쳐 보겠습니다.
1076+
1077+ ` ` ` typescript
1078+ // [1] 임포트 섹션 (생략)
1079+ import { ... } from " ..."
1080+ import { narrate } from " ../narrator.js" ;
1081+
1082+ // [2] 타입 정의
1083+ export type GatewayServer = {
1084+ close: (opts? : { reason? : string; restartExpectedMs? : number | null }) => Promise< void> ;
1085+ };
1086+
1087+ // [3] 사령관 함수: 서버 기동의 모든 단계를 지휘합니다.
1088+ export async function startGatewayServer(
1089+ port = 18789,
1090+ opts: GatewayServerOptions = {},
1091+ ): Promise< GatewayServer> {
1092+ // 1단계: 환경 변수 및 설정 준비
1093+ process.env.CLAWDBOT_GATEWAY_PORT = String(port);
1094+ let configSnapshot = await readConfigFileSnapshot ();
1095+
1096+ // 2단계: 레거시 설정 마이그레이션 (과거의 유산 정리)
1097+ if (configSnapshot.legacyIssues.length > 0) {
1098+ const { config: migrated, changes } = migrateLegacyConfig(configSnapshot.parsed);
1099+ await writeConfigFile(migrated);
1100+ log.info(` gateway: migrated legacy config entries` );
1101+ }
1102+
1103+ // 3단계: 장기(Subsystems) 초기화
1104+ narrate({ who: " startGatewayServer" , role: " 총사령관" , action: " 장기 부착 시작" });
1105+ const nodeRegistry = new NodeRegistry ();
1106+ const channelManager = createChannelManager({
1107+ loadConfig,
1108+ channelLogs,
1109+ channelRuntimeEnvs,
1110+ });
1111+
1112+ // 4단계: 실시간 통신망(WebSocket) 및 HTTP 서버 기동
1113+ const { httpServer, wss, clients, broadcast } = await createGatewayRuntimeState({
1114+ cfg: loadConfig (),
1115+ bindHost: " 0.0.0.0" ,
1116+ port,
1117+ // ... 기타 설정들
1118+ });
1119+
1120+ // 5단계: 신경망 핸들러 연결 (데이터가 흐르기 시작하는 지점)
1121+ attachGatewayWsHandlers({
1122+ wss,
1123+ clients,
1124+ port,
1125+ gatewayMethods,
1126+ logGateway: log,
1127+ broadcast,
1128+ context: {
1129+ // ... 서버의 모든 기능을 핸들러에 주입 (Dependency Injection)
1130+ nodeRegistry,
1131+ channelManager,
1132+ cron,
1133+ loadGatewayModelCatalog,
1134+ }
1135+ });
1136+
1137+ // 6단계: 외부 노출 및 보안 설정 (Tailscale 등)
1138+ const tailscaleCleanup = await startGatewayTailscaleExposure({ ... });
1139+
1140+ // 7단계: 기동 완료 보고
1141+ log.info(" 🚀 Gateway Server is ready for action!" );
1142+ narrate({ who: " startGatewayServer" , role: " 총사령관" , action: " 기동 완료 보고" });
1143+
1144+ // 8단계: 통제권 반환 (종료 버튼 제공)
1145+ return {
1146+ close: async (opts) => {
1147+ await close(opts); // 모든 장기 정지 및 메모리 해제
1148+ log.info(" 🛑 Gateway Server shut down safely." );
1149+ },
1150+ };
1151+ }
1152+ ` ` `
1153+
1154+ > [! TIP]
1155+ > ** 500줄의 전체 미로를 탐험하고 싶다면?**
1156+ > 실시간 업데이트되는 전체 원본 소스 코드는 프로젝트 내 [server.impl.ts](file:///Users/sl/Workspace/moltbot-2026.1.24/src/gateway/server.impl.ts) 파일에 보존되어 있습니다. 이 코드는 ** " 어떻게 70개의 파일이 하나로 꿰어지는가" ** 에 대한 정답지입니다.
1157+
1158+
1159+
10731160눈앞에 펼쳐진 ** 약 600줄의 코드** 가 위압적으로 느껴지십니까? 당연합니다.
10741161이곳은 단순한 코드가 아닙니다. 서버의 오감을 깨우고, 인공지능 두뇌를 연결하고, 전 세계와 통신하는 신경망을 지휘하는 ** " 사령부" ** 이기 때문입니다.
10751162
0 commit comments