Skip to content

Commit 1173930

Browse files
committed
docs: add completed code logic for server.impl.ts with detailed steps
1 parent 5debde8 commit 1173930

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

CLONE_MANUAL_DETAILED.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)