# XWorld 正式服务器部署(Windows + HTTPS/WSS) 把两个 .NET 进程部署到公网 Windows 服务器,用 **Caddy** 做 TLS 终止,对外只暴露 443。 | 进程 | exe | 监听(本机) | 对外(经 Caddy) | |------|-----|-----------|----------------| | 网关 大厅/对局 | `XWorld.Server.Gateway.Runner.exe` | `127.0.0.1:5005` (WS) | `wss://game.xworld.ren/ws` | | CDN 资源 | `XWorld.Server.Cdn.Runner.exe` | `127.0.0.1:15081` (HTTP) | `https://www.xworld.ren/game/60S/…` | > 两进程都**只绑 loopback**(不加 `--lan`),且**不开 DevDiscovery**(不传 `--devToken`)。公网只放 80/443,5005/15081 不对外。 --- ## 0. 前置准备 - Windows 服务器(管理员权限)。 - 三个域名 DNS A 记录指向本机公网 IP:`game.xworld.ren`、`www.xworld.ren`、裸域名 `xworld.ren`(主机名 `@`;换成你的真实域名,并同步改 `Caddyfile` 与客户端常量)。 - 裸域名一般不能用 CNAME,须用 A 记录直接指 IP。`xworld.ren` 与 `www.xworld.ren` 都会显示官网主页。 - 服务器防火墙放通入站 **80**(ACME 证书签发 + 跳转)和 **443**。 - 下载 [Caddy(Windows amd64)](https://caddyserver.com/download) 得 `caddy.exe`;下载 [NSSM](https://nssm.cc/download) 得 `nssm.exe`。 - 本机或开发机装 .NET 10 SDK(仅用于 `publish`;服务器因自包含发布**无需**装运行时)。 ## 1. 发布 在**装了 .NET 10 SDK 的机器**(如开发机)仓库根执行: ```powershell powershell -ExecutionPolicy Bypass -File deploy\windows\publish.ps1 ``` 产物在 `deploy\windows\out\{gateway,cdn}\`,并打包成 `deploy\windows\out\xworld-server.zip`。把 zip 拷到服务器解压到 `C:\xworld\app\`(得 `C:\xworld\app\gateway\`、`C:\xworld\app\cdn\`),`install-services.ps1` 用 `-OutRoot C:\xworld\app`。 > ⚠️ **必须跑自包含产物,别跑 `bin\Release`。** > `publish.ps1`(`--self-contained`)把 .NET 运行时 + ASP.NET 打进产物,服务器**无需装任何 .NET**。 > 而 `Server\...\bin\Release\net10.0\` 下的 exe 是 `dotnet build` 的**依赖框架版**,在没装运行时的服务器上会报 > `You must install .NET to run this application`。若坚持用 bin\Release,则需在服务器装 **ASP.NET Core Runtime 10.0 Hosting Bundle**(不是普通 .NET Runtime,网关/CDN 都用了 Kestrel)。 ## 2. 放置资源与小游戏模块 - **CDN 内容** → `C:\xworld\cdn\`,目录内须含 `XWorld\\…`(大厅基础更新:Unity 菜单「生成基础更新Android/Win64」产出,见 [仓库 CDN/README])与 `minigame\\\\…`(Unity 菜单「XWorld/生成小游戏更新」的客户端产物,platform=pc/android/ios/webgl)。即把仓库 `CDN\` 那套结构部署过去。 - **服务端小游戏模块** → `C:\xworld\games\`,结构 `games\\\*.dll`(`PublishTool` 服务端产物)。 - **官网主页** → `C:\xworld\site\`,须含 `index.html`(把仓库 `deploy\windows\site\` 拷过去即可)。`xworld.ren` 与 `www.xworld.ren` 的非 `/game/60S/` 路径都会返回这里的静态文件。 ## 3. 装成 Windows 服务 管理员 PowerShell: ```powershell powershell -ExecutionPolicy Bypass -File deploy\windows\install-services.ps1 ` -NssmPath C:\nssm\nssm.exe ` -OutRoot C:\xworld\app ` -GamesRoot C:\xworld\games ` -CdnRoot C:\xworld\cdn ``` 自检:`curl http://127.0.0.1:15081/XWorld/android/updatever.txt` 应 200。 ## 4. 配置并启动 Caddy - 编辑 `deploy\windows\Caddyfile`,把两个域名换成你的。 - 测试:`caddy run --config Caddyfile`(前台,看证书是否签发成功)。 - 装成服务(随机启动): ```powershell C:\nssm\nssm.exe install XWorldCaddy C:\caddy\caddy.exe C:\nssm\nssm.exe set XWorldCaddy AppParameters "run --config C:\xworld\Caddyfile" C:\nssm\nssm.exe set XWorldCaddy AppDirectory C:\xworld C:\nssm\nssm.exe set XWorldCaddy Start SERVICE_AUTO_START C:\nssm\nssm.exe start XWorldCaddy ``` ## 5. 验证(外网) - `https://www.xworld.ren/game/60S/XWorld/android/updatever.txt` → 200。 - WSS:用 wscat/浏览器连 `wss://game.xworld.ren/ws?pid=1`,能握手成功(不被拒绝)。 - 真机装新 APK(见第 6 步客户端改动后重打)→ 启动拉资源 → 登录连大厅成功。 --- ## 6. ⚠️ 必须的客户端改动(尚未应用,需要我做请说) 服务器就绪后,客户端**生产地址仍指向废弃的 TCP 7777**,必须改: | 文件:行 | 现状 | 改为 | |--------|------|------| | `Client/Assets/Script/xmain/GameLauncher.cs:290` 及 `:220` 回退 | `CurNode = "http://game.xworld.ren"` → 降级 TCP 7777 | `CurNode = "wss://game.xworld.ren/ws"`(`ConnectLobby` 直接走 WS) | | `Client/Assets/Script/xmain/GlobalData.cs:25` | `ProductionResBase = "http://www.xworld.ren/game/60S/"` | 改 `https://` | | `Client/Assets/Base/LoadDll.cs:157` | `http://www.xworld.ren/game/60S/XWorld//` | 改 `https://` | 改完需**重出 APK**(这几处在底包/热更层)。 ## 7. 鉴权与安全 1. **账号鉴权(已实现)**:`install-services.ps1` 给网关传 `--authDbPath C:\xworld\accounts.db` 即启用。 - 客户端经 `https://game.xworld.ren/register`、`/login`(账号+密码,PBKDF2)拿 HMAC 签名 token,再用 `wss://…/ws?token=` 连接;网关验签取权威 pid,明文 `?pid=` 在启用鉴权后不可用。 - **首启自动在 `accounts.db` 同目录生成 `auth.key`(HMAC 密钥)——务必备份**;丢失则所有已发 token 失效(用户需重登)。也可用 `--authSecret ` 显式指定。 - `/register`、`/login` 与 `/ws` 同主机,已被整域反代覆盖(无需额外 Caddy 规则)。 2. **传输安全**:Caddy TLS(WSS/HTTPS)。 3. **背压/限流(待办)**:出站 Channel 无界;登录可被暴力尝试。建议在 Caddy 加连接数/速率限制,并给网关加出站背压与登录失败锁定。 4. **吊销(待办)**:当前 token 无状态、靠过期(默认 7 天),暂不支持主动踢人/吊销。 ## 卸载 ```powershell powershell -ExecutionPolicy Bypass -File deploy\windows\uninstall-services.ps1 -NssmPath C:\nssm\nssm.exe # Caddy: nssm stop XWorldCaddy ; nssm remove XWorldCaddy confirm ```