WebSocket 配置
本文引用的文件
- src/config/v2_config.v
- src/ws/types.v
- src/websocket_runtime.v
- src/executor/inproc_vjsx_websocket_affinity_state.v
- src/executor/inproc_vjsx_websocket_policy.v
- src/executor/inproc_vjsx_websocket_lane_query_runtime.v
- examples/config/websocket-echo.toml
- config/vhttpd.example.toml
- docs/WEBSOCKET_MVP_PLAN.md
- docs/WEBSOCKET_EVENT_BUS_PLAN.md
- docs/WEBSOCKET_MESSAGE_DISPATCH_PLAN.md
目录
简介
本文件面向 vhttpd 的 WebSocket 能力,聚焦“可配置”的维度,覆盖连接管理、房间系统、消息处理、会话亲和性、安全、性能调优以及监控指标。文档以仓库中的实现与计划为依据,给出可直接落地的配置项说明、行为约定与最佳实践,帮助读者在不深入源码的情况下完成生产级部署与优化。
项目结构
WebSocket 相关能力在 vhttpd 中由“运行时上下文 + Hub 状态 + 执行器亲和策略 + 配置模型”共同构成: - 配置模型:V2 配置定义了监听器、TLS、并发策略等通用能力;WebSocket 通过引擎开关与并发策略进行启用与约束。 - 运行时上下文:封装了注册连接、加入/离开房间、广播、元数据读写、关闭目标等能力。 - Hub 状态:维护连接、房间成员、待发送队列、上游快照等。 - 执行器亲和策略:决定请求路由到哪个 lane(线程/进程槽位),支持从应用或查询参数解析亲和键。
graph TB
subgraph "配置层"
V2["V2 配置模型<br/>监听器/TLS/并发策略"]
end
subgraph "运行时层"
RT["WebSocket 运行时上下文<br/>注册/广播/元数据/关闭"]
HUB["Hub 状态<br/>连接/房间/待发送/上游"]
end
subgraph "执行器层"
AFF["亲和策略与迁移<br/>key 解析/引用计数/钉住"]
POL["亲和决策<br/>来源/键/优先级/钉住"]
end
V2 --> RT
RT --> HUB
RT --> AFF
AFF --> POL
图表来源 - src/config/v2_config.v:120-155 - src/websocket_runtime.v:26-94 - src/ws/types.v:361-377 - src/executor/inproc_vjsx_websocket_affinity_state.v:76-123 - src/executor/inproc_vjsx_websocket_policy.v:51-111
章节来源 - src/config/v2_config.v:120-155 - src/websocket_runtime.v:26-94 - src/ws/types.v:361-377 - src/executor/inproc_vjsx_websocket_affinity_state.v:76-123 - src/executor/inproc_vjsx_websocket_policy.v:51-111
核心组件
- 运行时上下文(RuntimeContext)
- 提供注册连接、打开/关闭生命周期、加入/离开房间、设置/清除元数据、广播、向指定连接发送、构建帧并派发事件等函数指针。
- Hub 状态(HubState)
- 维护连接表、房间成员映射、连接房间集合、连接元数据、待发送队列、分发模式开关、最近分发限制、动态上游自动启动、活动记录等。
- 亲和策略(Affinity Policy)
- 支持从应用回调或查询参数解析亲和键,支持优先级与是否钉住 lane 的策略,并在连接迁移时更新引用计数与映射。
- 配置模型(V2Config)
- 通过 engines.websocket_dispatch、policies.concurrency.* 等字段控制 WebSocket 分发与并发限流、队列、超时、亲和与 Actor 行为。
章节来源 - src/websocket_runtime.v:26-94 - src/ws/types.v:361-377 - src/executor/inproc_vjsx_websocket_policy.v:51-111 - src/config/v2_config.v:120-155
架构总览
vhttpd 作为本地 WebSocket Hub,负责连接生命周期与房间扇出;PHP/JS 执行器仅处理业务逻辑并返回命令列表。当前默认是“连接托管模式”,未来演进为“消息分发模式”。
sequenceDiagram
participant Client as "客户端"
participant Listener as "监听器(含TLS)"
participant WS as "WebSocket 内核"
participant Hub as "Hub 状态"
participant Exec as "执行器(Worker)"
Client->>Listener : "HTTP Upgrade 请求"
Listener->>WS : "握手/接管连接"
WS->>Exec : "open 事件帧"
Exec-->>WS : "accept/send/close 命令"
WS->>Hub : "注册连接/加入房间/设置元数据"
Client->>WS : "文本/二进制帧"
WS->>Exec : "message 事件帧"
Exec-->>WS : "send/broadcast/join/leave 命令"
WS->>Hub : "广播/加入/离开/发送"
Note over WS,Hub : "跨 worker 扇出由 Hub 负责"
图表来源 - docs/WEBSOCKET_MVP_PLAN.md:123-224 - docs/WEBSOCKET_EVENT_BUS_PLAN.md:205-270 - src/websocket_runtime.v:26-94 - src/ws/types.v:361-377
详细组件分析
连接管理与超时
- 最大连接数
- 未在 V2 配置中暴露全局上限字段;可通过并发策略的 in-flight/队列容量间接限制瞬时压力。
- 连接超时
- 读取超时通过引擎/worker 的 read_timeout_ms 控制;WebSocket 升级后由 net.websocket 内部 ping/pong 与 close 生命周期驱动。
- 心跳检测间隔
- 复用底层 net.websocket 的心跳机制;上层未暴露独立配置项。
建议 - 使用 policies.limits.timeout_ms 与 engines.read_timeout_ms 组合保护长连接。 - 结合 observability.event_log 观察连接建立/关闭事件。
章节来源 - src/config/v2_config.v:120-155 - src/config/v2_config.v:217-222 - docs/WEBSOCKET_MVP_PLAN.md:36-48
房间系统与广播
- 房间创建策略
- 隐式创建:首次 join 即存在;未知房间广播无操作。
- 成员管理
- HubState 维护 room_members 与 conn_rooms 双向映射;支持 set_meta/clear_meta。
- 广播机制
- 支持按房间广播并可排除特定连接;跨 worker 扇出由 Hub 统一处理。
章节来源 - src/ws/types.v:361-377 - docs/WEBSOCKET_EVENT_BUS_PLAN.md:205-270
消息处理配置(帧格式、opcode、二进制)
- 帧格式
- vhttpd -> worker:open/message/close 事件帧;worker -> vhttpd:accept/send/close/error 命令帧。
- opcode 类型
- 支持 text 与 binary;binary 采用 base64 编码传输。
- 二进制支持
- 测试用例验证 text/binary 支持,拒绝控制帧(如 ping/pong)。
章节来源 - docs/WEBSOCKET_MVP_PLAN.md:149-224 - src/websocket_binary_support_test.v:1-62
会话亲和性与路由
- 亲和键来源
- 支持 app 回调或 query/header 解析;支持优先级字符串/数字。
- 路由与钉住
- 根据 should_pin_lane 决定是否将 key 钉在当前 lane;迁移时维护引用计数与映射。
- 缺失键处理
- 当 enabled 且 fallback=reject 时,缺失亲和键直接拒绝。
flowchart TD
Start(["进入亲和决策"]) --> CheckEnabled{"亲和已启用?"}
CheckEnabled --> |否| ReturnEmpty["返回空键(不钉住)"]
CheckEnabled --> |是| ResolveKey["解析亲和键(app/query/header)"]
ResolveKey --> KeyEmpty{"键为空?"}
KeyEmpty --> |是| FallbackCheck{"fallback=reject?"}
FallbackCheck --> |是| Reject["拒绝请求"]
FallbackCheck --> |否| ReturnEmpty
KeyEmpty --> |否| PinCheck{"should_pin_lane ?"}
PinCheck --> |是| PinLane["钉住当前 lane"]
PinCheck --> |否| NoPin["不钉住"]
PinLane --> Done(["完成"])
NoPin --> Done
Reject --> Done
ReturnEmpty --> Done
图表来源 - src/executor/inproc_vjsx_websocket_policy.v:51-111 - src/executor/inproc_vjsx_websocket_affinity_state.v:76-123 - src/executor/inproc_vjsx_websocket_lane_query_runtime.v:44-75
章节来源 - src/executor/inproc_vjsx_websocket_policy.v:51-111 - src/executor/inproc_vjsx_websocket_affinity_state.v:76-123 - src/executor/inproc_vjsx_websocket_lane_query_runtime.v:44-75
安全配置(认证、ACL、TLS)
- TLS
- 监听器级别支持 TLS 证书与多证书 SNI;可在 listeners.*.tls 下配置。
- 访问控制
- 安全策略支持 required_headers、denied_query_patterns、allowed_origins。
- 身份认证
- 认证逻辑由应用侧实现;vhttpd 提供框架能力(如 allowed_origins、required_headers)辅助鉴权前置校验。
章节来源 - src/config/v2_config.v:28-50 - src/config/v2_config.v:224-229
性能调优参数
- 连接池大小
- engines.pool_size 控制执行器实例数量;WebSocket 模式下建议按消息吞吐而非连接数估算。
- 内存限制
- 未暴露显式内存上限;可通过 max_body_bytes、queue_capacity 控制单请求与队列规模。
- 网络缓冲区
- 未暴露独立缓冲配置;受限于操作系统与底层 net.websocket 实现。
- 并发与队列
- policies.concurrency.max_in_flight、queue_capacity、queue_timeout_ms、max_queue_per_key 用于背压与限流。
- 超时与重启
- engines.read_timeout_ms、restart_backoff_ms/max_requests 等影响稳定性与资源回收。
章节来源 - src/config/v2_config.v:120-155 - src/config/v2_config.v:217-222 - src/config/v2_config.v:243-259
依赖关系分析
- 配置到运行时
- V2 配置中的 engines.websocket_dispatch 与 policies.concurrency.* 被运行时上下文与执行器加载,驱动 WebSocket 分发与限流。
- 运行时到 Hub
- RuntimeContext 调用 HubState 方法完成注册、房间、广播、元数据等操作。
- 执行器到亲和策略
- 执行器在分发前解析亲和键,必要时迁移连接到目标 lane,并维护引用计数。
classDiagram
class V2Config {
+engines
+policies
+listeners
}
class WebSocketRuntime {
+register_conn()
+join()/leave()
+broadcast()
+set_meta()/clear_meta()
+close_target()
}
class HubState {
+conns
+room_members
+conn_rooms
+pending
}
class AffinityPolicy {
+value()
+decision_from_app_result()
+should_pin_lane()
}
V2Config --> WebSocketRuntime : "启用/限流"
WebSocketRuntime --> HubState : "读写状态"
WebSocketRuntime --> AffinityPolicy : "路由决策"
图表来源 - src/config/v2_config.v:120-155 - src/websocket_runtime.v:26-94 - src/ws/types.v:361-377 - src/executor/inproc_vjsx_websocket_policy.v:51-111
章节来源 - src/config/v2_config.v:120-155 - src/websocket_runtime.v:26-94 - src/ws/types.v:361-377 - src/executor/inproc_vjsx_websocket_policy.v:51-111
性能与调优
- 连接托管 vs 消息分发
- 当前默认“连接托管模式”:每个连接绑定一个 worker;未来“消息分发模式”可将连接与 worker 解耦,提升吞吐。
- 关键参数
- engines.pool_size、policies.concurrency.queue_capacity、queue_timeout_ms、max_queue_per_key、read_timeout_ms。
- 建议
- 以消息吞吐为目标评估 pool_size;对热点房间使用亲和键减少跨 lane 开销;开启 event_log 观测广播延迟与失败率。
章节来源 - docs/WEBSOCKET_MESSAGE_DISPATCH_PLAN.md:359-412 - src/config/v2_config.v:243-259
故障排查指南
- 常见问题
- 亲和键缺失导致拒绝:检查 enabled/fallback 与 key 来源(app/query/header)。
- 广播无效:确认房间是否存在、目标连接是否在线。
- 二进制异常:确保 opcode 为 'binary' 且 payload 为 base64。
- 定位手段
- 使用 observability.event_log 查看 open/message/close 事件与错误类。
- 通过 admin 接口或内置快照查看活跃连接、房间成员与元数据。
章节来源 - src/executor/inproc_vjsx_websocket_policy.v:51-111 - src/ws/types.v:361-377 - docs/WEBSOCKET_MVP_PLAN.md:123-224
结论
vhttpd 的 WebSocket 能力以“连接托管模式”为基础,逐步向“消息分发模式”演进。通过 V2 配置模型、Hub 状态与亲和策略,可实现跨 worker 的房间广播、稳定的路由与可扩展的吞吐。生产环境应结合并发策略、队列与超时参数进行调优,并通过事件日志与快照进行观测与排障。
附录:配置示例与监控指标
最小可用示例(WebSocket Echo)
- 监听器与文件
- server.host/port、files.pid_file/event_log
- Worker 与执行器
- worker.autostart/read_timeout_ms/socket/cmd、executor.kind、php.worker_entry/app_entry
- 静态资源与管理员
- assets.enabled/prefix/root/cache_control、admin.host/port/token
参考路径 - examples/config/websocket-echo.toml:1-28 - config/vhttpd.example.toml:1-67
关键配置项速查
- 引擎与分发
- engines[*].websocket_dispatch:启用 WebSocket 分发
- engines[*].pool_size:执行器实例数
- engines[*].read_timeout_ms:读取超时
- 并发与限流
- policies.concurrency[*].max_in_flight
- policies.concurrency[*].queue_capacity
- policies.concurrency[*].queue_timeout_ms
- policies.concurrency[*].max_queue_per_key
- 安全
- listeners[*].tls.enabled/cert/cert_key/certificates
- policies.security[*].required_headers/denied_query_patterns/allowed_origins
参考路径 - src/config/v2_config.v:120-155 - src/config/v2_config.v:217-222 - src/config/v2_config.v:224-229 - src/config/v2_config.v:28-50
监控指标收集方法
- 事件日志
- observability.event_log:记录 open/message/close、错误类、trace_id 等,便于离线分析与告警。
- 运行时快照
- 通过 ws.RuntimeSnapshot/ConnSnapshot/RoomSnapshot 获取活跃连接、房间成员与元数据。
- 上游活动
- UpstreamActivitySnapshot 记录事件处理链路、worker 处理结果与错误类。
参考路径 - src/config/v2_config.v:59-72 - src/ws/types.v:166-196 - src/ws/types.v:311-337