# XWorld 内层服务器部署文档 本文只说明 Caddy 后面的内层 .NET 服务部署:Gateway 与 CDN。公网 HTTPS/WSS 由 Caddy 负责,内层服务只监听本机 `127.0.0.1`,不要直接暴露公网。 ## 1. 服务组成 | 服务 | 程序 | 默认监听 | 给 Caddy 的用途 | | --- | --- | --- | --- | | Gateway | `XWorld.Server.Gateway.Runner.exe` | `127.0.0.1:5005` | 登录、注册、WebSocket 大厅/对局 | | CDN | `XWorld.Server.Cdn.Runner.exe` | `127.0.0.1:15081` | 静态资源下载 | 公网访问关系: ```text 客户端 -> https://game.xworld.ren / wss://game.xworld.ren/ws -> Caddy :443 -> 127.0.0.1:5005 客户端 -> https://www.xworld.ren/game/60S/... -> Caddy :443 -> 127.0.0.1:15081 ``` ## 2. 目录规划 建议服务器使用以下目录: ```text C:\xworld\app\gateway\ Gateway 发布产物 C:\xworld\app\cdn\ CDN Runner 发布产物 C:\xworld\games\ 服务端小游戏模块,结构 games\\\*.dll C:\xworld\cdn\ 客户端/CDN 内容,结构 XWorld\\... 和 minigame\\\\... C:\xworld\logs\ 服务日志 C:\xworld\accounts.db 账号 SQLite 库 C:\xworld\auth.key token HMAC 密钥,首次启动自动生成,务必备份 ``` ## 3. 发布内层服务 在开发机或服务器的仓库根目录执行: ```powershell powershell -ExecutionPolicy Bypass -File deploy\windows\publish.ps1 ``` 默认产物: ```text deploy\windows\out\gateway\XWorld.Server.Gateway.Runner.exe deploy\windows\out\cdn\XWorld.Server.Cdn.Runner.exe ``` 脚本使用 self-contained 发布,服务器不需要单独安装 .NET Runtime。 如果要发布到固定目录: ```powershell powershell -ExecutionPolicy Bypass -File deploy\windows\publish.ps1 -OutRoot C:\xworld\app ``` ## 4. 准备数据目录 创建目录: ```powershell New-Item -ItemType Directory -Force -Path C:\xworld\games New-Item -ItemType Directory -Force -Path C:\xworld\cdn New-Item -ItemType Directory -Force -Path C:\xworld\logs ``` 放置服务端小游戏模块: ```text C:\xworld\games\\\*.dll C:\xworld\games\\\game.json ``` 放置 CDN 内容: ```text C:\xworld\cdn\XWorld\android\updatever.txt C:\xworld\cdn\XWorld\pc\updatever.txt C:\xworld\cdn\minigame\\\\... ``` CDN Runner 的 `--root` 指向 `C:\xworld\cdn`,所以 Caddy 中 `/game/60S/*` 会被剥掉前缀后转发到该目录。 ## 5. 前台启动测试 先开两个 PowerShell 窗口测试。 Gateway: ```powershell C:\xworld\app\gateway\XWorld.Server.Gateway.Runner.exe ` --gamesRoot C:\xworld\games ` --port 5005 ` --authDbPath C:\xworld\accounts.db ``` CDN: ```powershell C:\xworld\app\cdn\XWorld.Server.Cdn.Runner.exe ` --root C:\xworld\cdn ` --port 15081 ``` 不要加 `--lan`。不加 `--lan` 时服务只绑定 `127.0.0.1`,这是生产推荐模式。 检查端口: ```powershell Get-NetTCPConnection -LocalPort 5005 -State Listen Get-NetTCPConnection -LocalPort 15081 -State Listen ``` 检查 CDN: ```powershell Invoke-WebRequest http://127.0.0.1:15081/XWorld/android/updatever.txt -UseBasicParsing ``` 检查 Gateway HTTPS 反代时,如果 Caddy 已启动: ```powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Invoke-WebRequest https://game.xworld.ren -UseBasicParsing ``` `https://game.xworld.ren` 没有首页时可能返回 404,但不应再是 502。502 表示 Caddy 连不上 `127.0.0.1:5005`。 ## 6. 注册为 Windows 服务 下载 NSSM: ```text https://nssm.cc/download ``` 假设 `nssm.exe` 位于: ```text C:\nssm\nssm.exe ``` 管理员 PowerShell 执行: ```powershell powershell -ExecutionPolicy Bypass -File C:\XWorld\AIC#Project\deploy\windows\install-services.ps1 ` -NssmPath C:\nssm\nssm.exe ` -OutRoot C:\xworld\app ` -GamesRoot C:\xworld\games ` -CdnRoot C:\xworld\cdn ` -AuthDbPath C:\xworld\accounts.db ` -LogDir C:\xworld\logs ``` 脚本会安装并启动: ```text XWorldGateway XWorldCdn ``` 查看状态: ```powershell Get-Service XWorldGateway,XWorldCdn ``` 启动/停止: ```powershell Start-Service XWorldGateway Start-Service XWorldCdn Stop-Service XWorldGateway Stop-Service XWorldCdn ``` 查看日志: ```text C:\xworld\logs\gateway.out.log C:\xworld\logs\gateway.err.log C:\xworld\logs\cdn.out.log C:\xworld\logs\cdn.err.log ``` ## 7. Gateway 参数说明 ```text --gamesRoot 服务端小游戏模块目录 --port Gateway 监听端口,默认 5005 --tickMs 服务 tick 间隔,默认 100 --matchTimeoutTicks 匹配超时 tick 数,默认 150 --authDbPath 启用账号鉴权,SQLite 数据库路径 --authSecret 可选,显式指定 HMAC 密钥 --lan 绑定所有网卡,生产不要加 --devToken 启用内网开发发现,生产不要加 --advertiseWs LAN 模式广播的网关地址 --advertiseCdn LAN 模式广播的 CDN 地址 --cdnPort LAN 模式广播 CDN 时使用的端口,默认 15081 ``` 生产建议: ```text --gamesRoot C:\xworld\games --port 5005 --authDbPath C:\xworld\accounts.db ``` 启用 `--authDbPath` 后,Gateway 会开放: ```text POST /register POST /login GET /ws?token= ``` 首次启动会在 `accounts.db` 同目录自动生成 `auth.key`。该文件用于验证 token,必须备份。丢失后旧 token 全部失效,用户需要重新登录。 ## 8. CDN 参数说明 ```text --root 必填,静态资源根目录 --port CDN 监听端口,默认 15081 --lan 绑定所有网卡,生产不要加 ``` 生产建议: ```text --root C:\xworld\cdn --port 15081 ``` ## 9. 与 Caddy 的联调 Caddyfile 应保持类似配置: ```caddyfile game.xworld.ren { encode zstd gzip reverse_proxy 127.0.0.1:5005 } www.xworld.ren { encode zstd gzip handle_path /game/60S/* { reverse_proxy 127.0.0.1:15081 } respond 404 } ``` 启动顺序建议: 1. 启动 `XWorldGateway` 2. 启动 `XWorldCdn` 3. 启动 Caddy 4. 从外网验证 HTTPS/WSS 验证: ```powershell Invoke-WebRequest https://www.xworld.ren/game/60S/XWorld/android/updatever.txt -UseBasicParsing Invoke-WebRequest https://game.xworld.ren -UseBasicParsing ``` `www.xworld.ren` 的资源文件应返回 200。`game.xworld.ren` 根路径可能返回 404,这是正常的;只要不是 502,就说明 Caddy 已连上 Gateway。 ## 10. 常见问题 ### Caddy 返回 502 含义:外层 HTTPS 正常,内层服务不可达。 检查: ```powershell Get-NetTCPConnection -LocalPort 5005 -State Listen Get-Service XWorldGateway Get-Content C:\xworld\logs\gateway.err.log -Tail 100 ``` ### CDN 文件 404 检查文件是否真的存在: ```powershell Test-Path C:\xworld\cdn\XWorld\android\updatever.txt ``` 检查本机 CDN: ```powershell Invoke-WebRequest http://127.0.0.1:15081/XWorld/android/updatever.txt -UseBasicParsing ``` ### Gateway 鉴权没有启用 启动日志中如果看到: ```text auth: OFF (dev ?pid=) ``` 说明没有传 `--authDbPath`。生产必须传: ```text --authDbPath C:\xworld\accounts.db ``` ### 服务对公网暴露了 5005 或 15081 生产不要使用 `--lan`。Windows 防火墙和云安全组也不要开放 `5005`、`15081` 入站。公网只开放 `80`、`443` 给 Caddy。 ### PowerShell HTTPS 测试提示 TLS 错误 旧版 Windows PowerShell 先执行: ```powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ``` 再执行 `Invoke-WebRequest`。