# WebSocket 验收记录(2026-10-29) 本次增加通用 WS Client/Server/Session、Hub、可选 RPC/订阅恢复、观测、App 生命周期与生成项目扩展。版本 `v0.31.0-preview` 已提交并推送,源码与远程发布验收记录如下。 ## 结论 - 功能、真实 TCP/TLS、并发竞态、静态检查、Go 1.22 兼容性和可运行 Go 示例通过。 - 最终全库回归输出见 [websocket-regression-go1.25.txt](websocket-regression-go1.25.txt);Go 1.27.3 下 `go test ./ws/...` 也通过。生成示例只同步 appGen 与清单,生成漂移检查及消费项目编译通过;新增生成消费回归验证了自定义路由和失败清理。 - Origin 模糊测试发现并修复无括号 IPv6 归一化歧义,失败样本保留在 `ws/testdata/fuzz/FuzzOrigin`;修复后 10 秒约 552,325 次执行通过。 - 新增核心包在隔离 Go 1.27.3 工具链、govulncheck v1.9.0 下扫描未发现已知漏洞。 - **包含 ws/omni 的完整接入安全扫描未通过**:仓库原有 `golang.org/x/net v0.33.0` 报告 4 项 HTTP/2 可达漏洞。不能将本次功能验收解释为整个框架已通过安全发布门槛。 - 浏览器自动化访问 `http://127.0.0.1:8088` 被浏览器权限策略拒绝,因此浏览器 UI/浏览器协议实测未完成;不以 Go 客户端测试代替这一项。示例源文件可供手动运行,临时服务已停止。 ## 远程发布验收 发布标签 `v0.31.0-preview` 固定在提交 `3272974bc1cd19c79efe7354b00b6ed67f27f51e`,已核对远程标签解引用结果。CLI 默认版本与框架版本一致,发布前再次通过全库 `go test ./...` 和 managedService 生成漂移检查。报告随后独立提交,不移动发布标签。 四组验收各自使用空 `GOMODCACHE`、临时 `GOBIN`、`GOWORK=off` 和 Go 1.25.0,从远程安装固定版本 CLI;消费项目均无本地 replace。四组校验和一致:`h1:d0sf951iJwMUtHj29D6BjUwOgg+C79GwQ+2vjAHLjDo=`。 | 验收 | 结果 | 报告 | | --- | --- | --- | | WS 发布包 | 6 个包、60 个顶层测试通过 race;11 项检查,含两个可运行示例、两代连接订阅恢复、生成路由与失败清理 | [WS 远程验收](websocket-remote.json) | | API 受管工程 | 110 项检查,含 11 组生成消费者与旧能力回归 | [API 远程验收](websocket-managed-remote.json) | | 通用工程 | 30 项检查 | [通用工程远程验收](websocket-program-remote.json) | | 混合工作区 | 16 项检查 | [工作区远程验收](websocket-workspace-remote.json) | 复验命令(在源码仓库根目录,PATH 选择所需 Go 工具链): ```sh python3 scripts/verifyWebsocketRelease.py --version v0.31.0-preview --report reports/websocket-remote.json python3 scripts/verifyManagedRelease.py --version v0.31.0-preview --report reports/websocket-managed-remote.json python3 scripts/verifyProgramRelease.py --version v0.31.0-preview --report reports/websocket-program-remote.json python3 scripts/verifyWorkspaceRelease.py --version v0.31.0-preview --report reports/websocket-workspace-remote.json ``` 这些结果确认发布内容的功能与消费可用性,不改变下文的工具链、HTTP/2 依赖安全结论和浏览器实测缺口。 ## 功能与并发验证 使用 Apple M2 Max / darwin arm64,主测试工具链 Go 1.25.0。独立 Go 1.22.12 用于最低版本兼容检查,没有替换系统 Go。 执行过: ```sh go test ./... go test -race -count=5 -timeout=120s ./ws/... ./examples/websocketRPC ./app ./httpx go test -race -coverprofile=/tmp/go-omni-websocket-coverage.out ./ws/... go vet ./ws/... ./app ./httpx ./examples/websocket ./examples/websocketRPC GOTOOLCHAIN=go1.22.12 go test ./ws/... ./app ./httpx go test ./ws -run '^$' -fuzz FuzzOrigin -fuzztime=10s -parallel=4 go test ./ws/rpc -run '^$' -fuzz FuzzProtocolDecode -fuzztime=10s go run ./examples/websocket go run ./examples/websocketRPC ``` 真实网络覆盖:回显、文本/二进制、128 个并行连接各 50 次往返、TLS/mTLS、HTTP CONNECT 代理认证、握手取消/超时、重连时刷新认证头、重试预算、快速重连与连接上限、双向嵌套 RPC、断线后两代 Session 的订阅恢复。 最终审查另修复了远端 `1001 going away` 被当成本地主动关闭、导致 Run 不重连的问题,并验证本地主动关闭仍停止重试;补充累计拨号/失败/重连指标和配置上界。修复后 `go test -race -count=3 ./ws/...` 通过。 安全与资源覆盖:同源/白名单/无 Origin/重复 Origin/null、拒绝错误子协议、认证拒绝与 panic、连接/握手速率限额、非法 UTF-8、压缩膨胀限额、发送数据拷贝、接收队列满、慢消费者、阻塞业务时仍处理 Ping/Pong、取消写入、断网、反复关闭、握手与停止并发、回调未退出时保留共享资源。 RPC 覆盖:双向请求、取消、迟到回复、重复在途 ID、未知字段、重复 JSON 键、嵌套深度、消息长度、pending/执行并发上限、公共与内部错误区分、panic 脱敏、订阅期望状态与恢复。RPC fuzz 10 秒约 71,268 次执行通过。 覆盖率快照: | 包 | 语句覆盖率 | | --- | ---: | | ws | 84.7% | | ws/hub | 86.5% | | ws/observe | 88.4% | | ws/omni | 86.7% | | ws/rpc | 80.7% | 覆盖率只描述这组测试执行到的代码,不等同于正确性或安全证明。测试不包含生产长时间浸泡、跨地区网络容量、HTTP/2 extended CONNECT 或 Autobahn 全套认证。 ## 性能基准 ```sh go test -run '^$' -bench . -benchmem -benchtime=500ms -count=3 ./ws/... ``` 原始输出:[websocket-bench-go1.25.txt](websocket-bench-go1.25.txt)。环境为 Apple M2 Max、Go 1.25.0、GOMAXPROCS=12、loopback、无 TLS、压缩关闭。三次样本的范围如下;首轮客户端样本与其它验证有时间重叠,保留原始波动,不选取单个最好值作为承诺。 | 基准 | 时间/操作 | 分配 | | --- | ---: | ---: | | Client 回声往返(9 B) | 26.0–47.3 μs | 1520 B / 13 allocs | | Server 回声往返(64 B) | 23.6–24.3 μs | 1568 B / 13 allocs | | Server 回声往返(1 KiB) | 26.4–30.6 μs | 7136 B / 17 allocs | | Server 回声往返(64 KiB) | 140.9–145.2 μs | 约 636 KB / 45 allocs | | Session 发送(256 B) | 5.34–5.37 μs | 1168 B / 9 allocs | | Hub 广播到 1000 个模拟连接 | 64.7–65.4 μs | 约 54.7 KB / 6 allocs | | 内存传输 RPC Call | 17.6–17.8 μs | 8386 B / 193 allocs | | 严格 RPC envelope 解析 | 4.68–4.89 μs | 3656 B / 106 allocs | 网络往返基准包括双方处理及本机 socket 成本;64 KiB 场景的分配包含双方完整读入及安全发送拷贝,后续大消息优化需在保持消息所有权的前提下进行。Hub 基准仅测注册表和分发,RPC 内存基准不包含网络。这里没有从单连接 loopback 数字外推生产 QPS 或最大连接数。 内存预算需按连接数乘以消息/队列上限估算,并额外计入解码中消息、协议缓冲和业务持有的 payload。默认 4096 连接上限并不意味着任何机器都能承受所有连接同时用满双向 4 MiB 队列。部署时需根据机器容量设置 MaxConnections、消息与队列字节数、RPC 执行并发;压缩及 TLS 应另做容量测量。 ## 漏洞扫描与剩余风险 扫描包含源码可达性分析,不是人工证明每条告警均可利用。没有隐藏、忽略或豁免扫描结果。 1. Go 1.25.0 + govulncheck v1.1.4 扫描 `./ws/...`:29 项标准库 symbol findings,以及 4 项 x/net symbol findings;Gorilla WebSocket 没有报告项。工具链版本是现有本机版本。扫描结果摘要保留在 [JSON](websocket-vuln-go1.25.json)。 2. 隔离 Go 1.27.3 + govulncheck v1.9.0 扫描 `./ws/...`:标准库告警消除,剩余 4 项 x/net HTTP/2 findings,详见 [完整输出](websocket-vuln-patched-go.txt)。 3. 同一修补工具链扫描 `./ws ./ws/hub ./ws/rpc ./ws/observe`:`No vulnerabilities found.`,见 [输出](websocket-vuln-core-patched-go.txt)。这不覆盖 ws/omni 引入的原有 App/HTTP2 依赖图。 剩余报告:GO-2026-6617(HPACK 并发)、GO-2026-6612(流控退款)、GO-2026-6611(重复窗口变更 CPU)、GO-2026-6603(Trailer 内存)。扫描器给出的修复版本为 `golang.org/x/net v0.60.0`;它的 [官方 go.mod](https://raw.githubusercontent.com/golang/net/v0.60.0/go.mod) 要求 Go 1.26,并升级 x/crypto、x/sys、x/text。此变更会改变框架当前公开的 Go 1.22 基线与多个既有适配器,未在 WS 功能提交中隐式实施。需要作为明确的框架安全升级进行全库与消费项目回归,生产发布前解决。 生产应使用受支持且已修补的 Go 工具链。Go 1.22 测试只验证源码兼容,不代表该旧工具链具备当前安全修复。对应标准库证书问题的官方说明见 [GO-2026-6809](https://pkg.go.dev/vuln/GO-2026-6809);HTTP/2 问题见 [GO-2026-6617](https://pkg.go.dev/vuln/GO-2026-6617)。