开发实录
为什么我们重新设计了 WebSocket Mock DSL,而不是用 YAML、JSON 或 JS
轻量 Mock,不该先变重
HTTP 联调里,Mock 很轻:抓一帧,勾特征,改响应。一来一回就结束。
WebSocket 的轻量场景其实差不多短:连上、登录、回一句、隔几秒推个心跳。要 mock 的是一小段对话,不是一篇程序。
现成方案却常把这段对话塞进 JSON 规则表、YAML 配置、或一段 JS。功能很强,也能跑。 问题是:本来十来行能说完的事,要先填字段、堆括号、写 setInterval。轻量 Mock 先被容器写重了。
我们重新设计了一套 DSL,图的就是这件事——让轻量 Mock 更轻。界面叫 WS Flow,文件是 .dpws。人写剧本;JSON 只当编译产物。
同一段对话
「连上 challenge → 登录成功 → 每 15 秒 tick」,规则 JSON 常见是这样:
{
"url": "wss://api.example.com/ws",
"onOpen": [{ "send": { "type": "challenge" } }],
"handlers": [
{
"match": { "type": "login" },
"reply": { "type": "loginSuccess" },
"then": {
"every": "15s",
"send": { "type": "tick" }
}
}
]
}
字花在 onOpen、handlers、match、reply、then 上。YAML 少了括号,壳还在:键、列表、再套一层,缩进既像配置又像对话。JS 最能打,一段 Mock 也容易变成小程序。
同一段,Flow 是这样:
# ws wss://api.example.com/ws
# profile type
# ping auto
--@open
challenge
--login
loginSuccess
--@loop 15s
tick
--@open 是连上,--login 是客户端登录,缩进里的是回什么、之后怎么推。loginSuccess 按文件头编成 {"type":"loginSuccess"},业务帧不必每次手写 JSON。延迟、周期推送写在行上(+300ms、--@loop 15s),不必另起控制流。
语法就这些:缩进树,加少量符号(--、--@、~scope、|、$、+delay、!close)。没有 if/for/函数。场景见 WebSocket Mock,符号见 .dpws 语言参考。
HTTP Mock 仍从抓包、GUI 走;WS Flow 只服务这种短对话。两条不要揉成一张表。
轻的用 DSL,重的仍用 JS
Flow 只对准轻量 Mock:顺序的一小段会话。并发乱序、深分支、动态或随机 payload、要读外部数据——YAML/JSON 的生态(Schema、diff、CI)或直接写 JS 更合适。那不是 DSL 没写完,是我们不想把轻量语法撑成通用语言。
自研也有账:解析器、报错、高亮、补全都要自己养,同事要学新符号。校验已经接到编辑器,高亮和补全还早。换来的是:打开文件就像在读对话,而不是在读配置。
和前两篇是同一条线
抓包历史从 sql.js 迁到原生 SQLite,解决的是挂久了的存储。
桌面壳从 Electron 换成 Tauri,解决的是壳太重。
这篇是:轻量长连接 Mock 不该先被 JSON/YAML/JS 写重。我们用更短的 DSL,让它保持轻。
相关文档
欢迎 下载 DevPeek 看 HTTP Mock 与抓包怎么串;WS Flow 以 WebSocket Mock 文档 为准。不同看法可以到 GitHub Discussions 聊。