NapCat 与 Stapxs QQ Lite 部署排障 (NapCat & Stapxs QQ Lite Troubleshooting)
1. 架构与背景
在部署基于 NTQQ 核心的机器人协议端 NapCat (NapCat.Onebot) 与第三方 Web 客户端 Stapxs QQ Lite (napcat-plugin-ssqq) 时,典型网络拓扑如下:
+--------------------------+
| Stapxs QQ Lite (Web UI) |
+-------------+------------+
|
| WSS (https://napcat.example.com/ws)
v
+--------------------------+
| Nginx Gateway |
+-------------+------------+
|
| WS (127.0.0.1:3001)
v
+--------------------------+ +--------------------------+
| NapCat OneBot 11 (Core) | <------> | AstrBot / Other Client |
+--------------------------+ +--------------------------+
|
| Native NTQQ API
v
+--------------------------+
| Linux QQ |
+--------------------------+- NapCat 协议端:同时维护针对机器人的反向 WebSocket 客户端(如连接 AstrBot
127.0.0.1:6199)与针对人类管理/客户端的正向 WebSocket 服务端(监听127.0.0.1:3001)。 - Stapxs QQ Lite 插件:以 NapCat 插件扩展页面形式注入,其前端静态资源由 NapCat Web 服务(端口 6099)托管在
/plugin/napcat-plugin-ssqq/files/static/。 - Nginx 网关:负责处理外部 SSL 证书终端,并将
/ws前缀路由反向代理至正向 WebSocket 服务端口(3001)。
2. 常见故障与深度根因分析
故障 1:点击“去连接”无任何弹窗且页面卡死/空白
现象
在设置界面看到“还没有连接到 OneBot 耶”,点击右侧的“去连接”按钮后,没有任何配置弹窗弹出,页面停留在空白主页,用户无法配置连接地址。
深度根因
按钮实现逻辑:
在ViewOptAccount组件中,“去连接”按钮的代码为:function c() { var f; (f = document.getElementById("bar-home")) == null || f.click(); }该按钮本身并非弹窗触发器,其本意仅是触发侧边栏“主页”(Home)图标的点击事件。
构建时条件隐藏:
在napcat-plugin-ssqq专用构建分支中,作者设置了环境变量VITE_NAPCAT=1,导致主页的连接表单被硬编码条件隐藏:// setup 中 l="1" s(v).page == "Home" ? t("div", t5, [ s(l) ? H("", !0) : p("div", n5, [ /* 连接到 OneBot 表单 */ ]) ])因为
s(l)恒为真,主页上的表单直接被渲染为注释节点<!-- -->。- 内置快速连接失效闭环:
该插件原本设计为读取父级 WebUI 的localStorage.getItem("token")并调用/api/Debug/create创建临时调试适配器。然而 NapCat WebUI 的 Session 凭据默认仅 1 小时有效(WithinOneHour),一旦过期或未命中,快速连接抛出 401 失败。而主页表单又被s(l)隐藏,导致用户完全被锁在无界面的死循环中。
故障 2:外部赞助商接口异常导致 Vue 渲染崩溃
现象
浏览器控制台报出:
TypeError: Cannot read properties of undefined (reading 'length')
at Proxy.<anonymous> (main-xxx.js)整个 Web 客户端界面白屏卡死,所有交互无响应。
深度根因
客户端启动时会请求远程接口 https://api.stapxs.cn/ssqq/sponsor。当远程服务端由于缺少参数返回 {"error":"params incomplete"} 时,前端代码未对返回对象中预期的列表字段做空值防御,直接访问 .length 导致整个 Vue 组件树崩溃。
故障 3:WebUI 网络配置删除后客户端断连
现象
在 NapCat WebUI 的“网络配置”界面误删正向 WebSocket 配置后,端口 3001 监听消失,外部客户端连接报错 502 Bad Gateway 或 404/401。
深度根因
NapCat 的网络拓扑配置保存在 config/onebot11_<uin>.json。当在管理界面删除对应条目时,websocketServers 数组被置空。此时 Nginx 的 /ws 代理无后端可连。
3. 解决步骤与规范操作
步骤 1:恢复 NapCat 正向 WebSocket 服务器
检查并编辑 NapCat 配置文件(位于 NapCat 目录下的 config/onebot11_<uin>.json),在 network.websocketServers 数组中添加正向服务:
{
"network": {
"websocketServers": [
{
"name": "ssqq-ws",
"enable": true,
"host": "127.0.0.1",
"port": 3001,
"messagePostFormat": "array",
"reportSelfMessage": false,
"token": "",
"enableForcePushEvent": true,
"debug": false,
"heartInterval": 30000
}
]
}
}重启 NapCat 服务并验证监听:
sudo systemctl restart napcat-<uin>.service
ss -tlnp | grep 3001步骤 2:配置 Nginx WSS 反向代理(前缀匹配)
在 Nginx 配置中,为 WebSocket 端点配置前缀匹配规则(避免因尾部斜杠导致 401/404):
location ^~ /ws {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_buffering off;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}测试并重载 Nginx:
sudo nginx -t && sudo systemctl reload nginx步骤 3:修复 Stapxs QQ Lite 前端代码
编辑插件静态资源 plugins/napcat-plugin-ssqq/webui/dist/assets/js/main-*.js:
- 解除主页连接表单隐藏:
将l="1"替换为l=!1,确保在未连接时主页能够正常显示“连接到 OneBot”卡片。 自动预填当前站点的 WSS 地址:
将:Le.address = k.sysConfig.address, Le.connectionHistory = du()替换为:
Le.address = k.sysConfig.address || (location.protocol === "https:" ? "wss://" : "ws://") + location.host + "/ws", Le.connectionHistory = du()- 开启后端信息展示与退出连接入口:
在ViewOptAccount中将o="1"替换为o=!1。
4. 验证与复用要点
测试 WSS 握手:
python3 -c " import ssl, socket ctx = ssl.create_default_context() ctx.check_hostname = False; ctx.verify_mode = ssl.CERT_NONE s = socket.create_connection(('127.0.0.1', 443)) ss = ctx.wrap_socket(s, server_hostname='napcat.example.com') req = 'GET /ws HTTP/1.1\r\nHost: napcat.example.com\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nSec-WebSocket-Version: 13\r\n\r\n' ss.sendall(req.encode()) print(ss.recv(1024).decode().split('\r\n')[0]) ss.close() " # 输出为 HTTP/1.1 101 Switching Protocols 即代表握手正常用户端使用流程:
- 浏览器按
Ctrl + F5强制刷新 NapCat 插件页面。 - 主页直接呈现连接卡片,地址栏已自动填充
wss://napcat.example.com/ws。 - 连接密钥留空,勾选“记住密码”与“自动连接”,点击“连接”即可进入完整聊天界面。
- 浏览器按
本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/AI apps