生命周期(--@)
生命周期条件不依赖客户端业务消息,而是连接事件:`--@open` 连接建立、`--@loop` 周期推送、`--@ping` 协议 Ping、`--@close` 断开等。常用于欢迎语、心跳、协议层 Pong。
生命周期条件匹配 非 client JSON 业务帧,而是连接/协议/定时事件。
语法:行首 --@ + 事件名(+ 可选参数)。@ 为保留字,业务 JSON 字段勿与 --@ 混淆。
事件一览
| 条件 | 触发时机 | 次数 | 典型用途 |
|---|---|---|---|
--@open |
Mock 接管连接,WS 握手完成 | 每连接 1 次 | welcome、challenge、初始推送 |
--@ping |
收到 client 协议级 Ping 帧 | 每次 ping | 自定义 pong(否则 # ping auto) |
--@pong |
收到 client 协议级 Pong 帧 | 每次 pong | 少见;可忽略或日志 |
--@close |
收到 Close 帧或连接即将结束 | 每连接至多 1 次 | 最后一帧通知、清理 |
--@loop <dur> |
连接存活期间定时 | 周期性 | tick、heartbeat、行情推送 |
<dur> 格式:500ms、2s、1m、5s;纯数字无单位视为毫秒(如 5000 = 5000ms)。
解析优先级(条件行统一入口)
- 行首
--@→ 生命周期条件(本节) - 否则 → 第六节消息条件
各事件语义
--@open
- Flow match 命中且连接建立后触发一次
- 其下平级返回按 5.1 顺序发出(server 主动推送,无需 client 先发消息)
- 可挂子条件(消息或生命周期),发完 open 返回后按 scope 规则进入子树
- 可选 capture(实现):$connectionId、$subprotocol 写入连接上下文
- 典型:连上发 challenge → 等 client auth → 再开 tick
--@open
{"type":"challenge","nonce":"mock-nonce"} +0ms
--type=connect
{"type":"connected","ok":true} +0ms
--@loop 10s
{"type":"tick"} +0ms
--@ping / # ping auto
- 协议级 Ping(WebSocket opcode ping),payload 可为空
# ping autoon:未命中--@ping时,runtime 自动回 protocol Pong(空 payload)--@ping下返回:按返回行发出 text 帧(若写 "pong");不自动混用 protocol pong- Mock 且
# upstream off时:validate 要求# ping auto on或存在--@ping(否则 E008) - 与应用层
--type=ping无关
--@pong
- 协议级 Pong;多数场景无需分支,预留供测试/日志。
--@close
- client 发 Close 或连接 teardown 时触发
- 其下返回:断线前最后一帧(若来得及发出)
- 触发后取消该连接所有
--@loop定时器 - 不替代 server 主动关连接;主动关见 8.3
!close
--@loop <dur>
- 连接存活期间,每隔 dur 触发一次(server 主动推送)
- 其下返回:每次 tick 执行(支持管道、$、+delay;+delay 相对 tick 触发时刻)
- 绑定 scope 栈帧:仅在其 所属 scope 帧 active 期间运行(见第十七节)
- 进入 scope 且到达 loop 节点 → register timer;离开 scope 帧(pop)→ cancel
- 连接关闭或
--@close→ cancel 该连接全部 timer - 首 tick:
# loop immediate off时首个 tick 在 dur 之后;on 时注册后立即 tick
--@loop 注册时机表(Normative)
| 位置 | start | stop |
|---|---|---|
根级(与 --@open 同级) |
WS 建立且 Flow 命中后,root 帧 active | 连接关闭 / !close / --@close |
--@open 的直接子节点 |
--@open 触发且 open 下 同级返回发完 后 |
离开 --@open 子树 scope / !~session 等 pop |
| 挂在返回子树深处 | scope 激活且 遍历到达 loop 节点 时 | pop 该 loop 所在帧或任意祖先帧 |
在 --login ~auth 等命名 scope 内 |
进入 ~auth 帧 active 后 |
!~auth 或 pop auth 及其祖先 |
同一 scope 帧上多个 --@loop 兄弟:各自独立 timer。
>> 与 --@open 的关系
根级 >> 是语法糖,编译为:
--@open
<原 >> 行内容>
多条根级 >> 合并为同一 --@open 下的平级多返回(5.1 顺序执行)。
需要「连上推送 + 后续 scope」时,请写完整 --@open 树,不要仅用散装 >>。
生命周期条件与 capture
# capture 默认只对 消息条件 匹配成功的 JSON 帧生效。
--@open 等生命周期事件不 capture client JSON(无帧或无可 parse JSON)。
实现可选:--@open 时 capture 连接元数据到 $connectionId 等。
生命周期 + scope
与消息条件相同:--@open 等触发 enter 根 runBranch(§17.4)— 顺序扫描平级子节点;enter 结束后 push 帧并移入匹配上下文(§5.2、§17.4)。
缩进在 返回行 下的子条件:下帧在 scope 移入后匹配;与 entry 平级 的子 -- 可在 同帧 scan 中匹配(§5.2)。
--@loop 作为子条件时,在 enter 结束且 scope 帧激活 后 register(步骤 5);该帧 pop 时 cancel。
命名 scope 规则见 6.9 与第十一节。