
























项目:NewRingGame(Unity WebGL + .NET 7 API)
环境:CentOS 7、宝塔面板、同机部署
WebGL:https://mini.vrast.cn/
API:https://server.vrast.cn
部署目录:/www/wwwroot/ringgame
《恶魔轮盘》联机版采用 Unity WebGL 客户端 + .NET 7 服务端 架构。首次上生产时,WebGL 与 API 部署在同一台 CentOS 7 服务器,通过宝塔面板管理 Nginx、进程与 FTP。
联调过程中,HTTP 登录接口已经可用,但游戏界面长期停在 「连接 Hub…」,无法进入在线大厅。本文记录从部署到联机打通的完整排查过程与最终解法。
CentOS 7 官方源没有 .NET 7 包,不能照搬 Ubuntu 的 apt install。
做法: 使用微软安装脚本安装 ASP.NET Core 7 运行时:
1 | curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --runtime aspnetcore --channel 7.0 |
发布包中附带 install-dotnet-runtime.sh、run-prod.sh,便于在宝塔里一键启动。
错误示例: 把环境变量写在整条命令最前面,宝塔进程守护可能解析失败。
1 | ASPNETCORE_ENVIRONMENT=Production nohup dotnet ... |
推荐:
/www/wwwroot/ringgame/run-prod.sh ExecStart=/usr/bin/dotnet /www/wwwroot/ringgame/NewRingGame.Server.dll run-prod.sh 或 systemd Environment= 中设置宝塔站点目录属主多为 www:www,权限 drwxr-xr-x,FTP 用户不在 www 组时无法写入。
做法:
1 | chmod 775 /www/wwwroot/ringgame |
GM 面板发布默认 FTP 主机 server.vrast.cn,远端目录 /www/wwwroot/ringgame。
宝塔本地 MySQL 连接时,若未配置 SSL,.NET 驱动可能报 SSL 相关错误。
做法: 连接串增加:
1 | SslMode=None |
Nginx 终止 HTTPS 后,Kestrel 收到的是 HTTP 请求,需正确识别客户端 IP 与原始协议。
Program.cs 已配置:
UseForwardedHeaders():识别 X-Forwarded-For、X-Forwarded-ProtoAssets/Resources/Network/NetworkSettings.json 生产段示例:
1 | { |
派生地址:
https://server.vrast.cn/apiwss://server.vrast.cn/hub/game?access_token={token}POST /api/auth/login → 返回 JWT token/hub/game?access_token=...GameHub.OnConnectedAsync 校验 token,失败则 Context.Abort()因此:登录 200 只说明 HTTP 正常;卡在「连接 Hub…」说明 WebSocket 阶段有问题。
| 项目 | 状态 |
|---|---|
GET /health |
200 |
POST /api/auth/login |
200,有 token |
| CORS 预检 | 正常,Access-Control-Allow-Origin: https://mini.vrast.cn |
| 游戏界面 | 停在「连接 Hub…」 |
| DevTools → Network → Socket | 无连接,或 Unity 侧无后续日志 |
Console 可见 [GameHub] 连接 wss://server.vrast.cn/hub/game,但无「握手成功」或明确报错。
第一层:服务端 HTTP 是否正常
1 | curl -s https://server.vrast.cn/health |
第二层:浏览器原生 WebSocket 是否正常
在 https://mini.vrast.cn/ 控制台执行(替换真实 token):
1 | const ws = new WebSocket("wss://server.vrast.cn/hub/game?access_token=你的token"); |
若输出 「WS 成功」,则 Nginx 反代与 Hub 均已正常,问题在 Unity WebGL 客户端。
第三层:Unity 客户端
WebGL 上 System.Net.WebSockets.ClientWebSocket 不可靠;配合 ConfigureAwait(false)、Task.Run 会导致异步回调无法继续,界面永久停在「连接 Hub…」。
宝塔 → 软件商店 → Nginx → 配置修改,在 http { 内、server { 前加入:
1 | map $http_upgrade $connection_upgrade { |
原配置主要问题:
| 问题 | 原值 | 修正 |
|---|---|---|
| Host 头 | 127.0.0.1:$server_port |
$host |
| 转发协议 | 缺失 | X-Forwarded-Proto $scheme |
| Connection | 固定 "upgrade" |
$connection_upgrade |
| Hub 路径 | 与普通 API 混用 | 单独 location /hub/ |
| 发送超时 | 30s |
86400s(长连接) |
/hub/ 示例:
1 | location /hub/ { |
直接删改 SSL / 错误页注释块会导致 「配置文件保存失败」。必须保留:
#SSL-START 内的 #error_page 404/404.html;#ERROR-PAGE-START … #ERROR-PAGE-END 整段#CERT-APPLY-CHECK--START/END#HTTP_TO_HTTPS_START/END只改 location 反代部分,不要动上述标记块。
保存后执行:
1 | nginx -t && nginx -s reload |
| 问题 | 说明 |
|---|---|
ConfigureAwait(false) |
WebGL 无线程池,continuation 无法执行 |
Task.Run |
WebGL 不支持,接收循环无法启动 |
ClientWebSocket |
浏览器测试 WS 成功,Unity 侧仍挂起 |
WebGL 改用 浏览器原生 WebSocket(jslib):
| 文件 | 作用 |
|---|---|
Assets/Plugins/WebGL/BrowserWebSocket.jslib |
JS 层 WebSocket 封装 |
Assets/Scripts/Network/BrowserWebSocketTransport.cs |
C# 桥接 |
Assets/Scripts/Network/SignalRWebSocketClient.cs |
WebGL 自动选择传输层 |
其他改动:
GameHubClient:20 秒连接超时NetworkConfig:443 端口省略 :443(wss://server.vrast.cn/hub/game)UnityEngine.Debug.Log,避免与 DemonRoulette.Debug 命名空间冲突Console 应出现:
1 | [GameHub] 连接 wss: |
随后进入在线大厅(房间列表)。
DemonRouletteWs is not defined登录后 Hub 连接阶段,浏览器弹出 Unity 运行时错误,Console 完整堆栈类似:
1 | Uncaught ReferenceError: DemonRouletteWs is not defined |
原因: 第一版 BrowserWebSocket.jslib 在 mergeInto 外部声明了全局变量:
1 |
|
Unity / Emscripten 只会把 mergeInto(LibraryManager.library, ...) 内的符号打进 framework.js。外部 var 在 WebGL 运行时不可见,C# 通过 [DllImport("__Internal")] 调用 _DemonRoulette_WsCreate 时就会崩溃。
正确写法: 使用 Emscripten 的 $ 依赖语法保存状态,并 autoAddDeps:
1 |
|
如何确认已部署新包:
WebGL-Staging.framework.js(解压 .br 后)DemonRouletteWs → 不应存在drrWsState → 应存在若仍能看到 DemonRouletteWs,说明上传的是旧 Build,或 Service Worker / IndexedDB 缓存了旧 framework.js(URL 带 ?v=legacy.1.1.1... 时尤其容易误判「已更新」)。
mini.vrast.cnWebCacheRepair)127.0.0.1:8080,Nginx 反代到 443curl /health 与 curl login 均正常SslMode=None(宝塔本地库)ForwardedHeaders、CORS 已启用map $http_upgrade $connection_upgradeHost 为 $host,非 127.0.0.1X-Forwarded-Proto $scheme/hub/ 单独 location,proxy_buffering offNetworkSettings.json release 段指向生产域名BrowserWebSocket.jslib(非纯 ClientWebSocket)| 用途 | 路径/地址 |
|---|---|
| WebGL 站点 | https://mini.vrast.cn/ |
| API / Hub | https://server.vrast.cn |
| 服务端部署 | /www/wwwroot/ringgame |
| GM 发布面板 | server/scripts/dev-manager/app.py |
| 网络配置 | Assets/Resources/Network/NetworkSettings.json |
| Hub 服务端 | server/src/NewRingGame.Server/Hubs/GameHub.cs |
| 登录 UI | Assets/Scripts/UI/OnlineNetworkUiBinder.cs |
本次联机打通,问题并不在「登录接口」,而在 Hub WebSocket 全链路:
/hub/ 独立规则)ClientWebSocket + ConfigureAwait(false),必须走浏览器原生 WebSocket排查顺序建议:HTTP 健康检查 → 登录 API → 浏览器 WS 测试 → Unity 包与缓存。当浏览器 new WebSocket(...) 已成功而 Unity 仍卡住时,应优先怀疑 WebGL 网络实现,而非继续改 Nginx。
归档日期:2026-06-06
本文标题:.net core服务发布经验总结
文章作者:Keyle
发布时间:2026-06-12
最后更新:2026-06-12
原始链接:https://vrast.cn/posts/4461/
版权声明:©Keyle's Blog. 本站采用署名-非商业性使用-相同方式共享 4.0 国际进行许可
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。