WebSocket Mock
DevPeek can mock multi-turn WebSocket dialogs with `.dpws` Flow files—login, heartbeats, rooms, logout, and more. This page covers **when and how to start**; full syntax lives in the separate .dpws language reference.
WebSocket Mock is being wired into the DevPeek desktop app. You can draft `.dpws` files now using this guide and the language reference; in-app rule entry will follow. For HTTP Mock, see Mock/Breakpoint.
How it differs from HTTP Mock
Mock/Breakpoint fits one-shot HTTP request/response. WebSocket stays open: login, heartbeat, join room, logout—many turns on one connection, so Mock is a conversation tree.
- HTTP Mock: one request → one response (tamperable).
- WebSocket Mock: multi-turn on a live connection; can simulate server push (e.g. heartbeats).
- Rule body is an indented Flow text file; prefer the `.dpws` extension.
What the config file is
One WebSocket Mock rule is one Flow (`.dpws`). When enabled in DevPeek, matching WebSocket connections follow the Flow as if the server spoke that dialog.
- Leading `# …` lines: URL, field conventions, auto Pong, etc.
- Indented body: `--condition` matches client messages; lines below are replies.
- Use 4 spaces or tabs consistently—do not mix.
How to read a Flow
Mental model: replies are the point; `--` conditions are gates—only matching branches emit their returns.
- `--login`: enter this branch when the client message looks like login.
- Indented `loginSuccess`: send one frame (a bare word becomes JSON with type loginSuccess).
- Several returns under one condition fire in source order; add `+300ms` for delay.
- Nest child conditions under a parent; if the same frame also matches, more replies can fire in that turn.
- On a live connection you also track **scope (phase)**: enter `~auth` on login, exit with `!~auth` on logout—to split logged-in vs not and to control push timers like heartbeats (see next section).
Getting-started example
Minimal Flow: login → success, app ping → pong. Tune `--` conditions against decrypted JSON from Capture:
# ws wss://api.example.com/ws
# profile type
# dispatch type
# format json
# ping auto
--login
loginSuccess
--ping
pongScope: phases on a connection
A **scope** is which business **phase** the WebSocket connection is in—e.g. not logged in, in the `auth` login phase, or inside a room. It is not a bag of field values; it tracks “which part of the dialog we are in”. Scope affects two things: which `--` conditions can match client messages, and whether `--@loop` timers keep pushing.
- **Enter**: append `~name` on a condition line (e.g. `--login ~auth`). After the branch matches and its returns are sent, the connection enters the `auth` phase; the indented subtree under that return becomes the preferred match context for later messages.
- **Exit**: use `!~name` (e.g. `--logout !~auth`). The line matches only if the connection is **already** in that phase. On match, the phase ends first (all timers under that phase and nested phases stop), then returns are sent.
- **Split branches**: the same client event can have multiple lines—logged-in clients hit `!~auth`, logged-out clients hit plain `--logout`. If `auth` is not on the stack, `--logout !~auth` does not match at all (no accidental no-op).
- **With push timers**: `--@loop` under a phase’s return subtree runs only while that scope is active; leaving the scope stops it—no separate “stop heartbeat” return needed.
- **Nested phases**: you can enter `~room1` inside `~auth` (e.g. join room). `!~auth` pops inner phases too and cancels their timers.
Connect (no scope yet)
│
│ client login → matches --login ~auth
▼
~auth active ────────► heartbeat push starts
│
│ client logout → matches --logout !~auth
▼
auth ended (heartbeat stops)Login / logout is the classic scope story: `~auth` owns login state and heartbeat; two `--logout` lines cover logged-in vs not-logged-in:
# profile type
# dispatch type
# format json
# ping auto
--login ~auth
loginSuccess
--@loop 5s
heartbeat
--logout !~auth
logoutSuccess
--logout
notLoggedIn- `--login ~auth`: after loginSuccess, enter auth; `--@loop 5s` under that return pushes `heartbeat` every 5s.
- `--logout !~auth`: matches only while logged in; leaves auth, stops heartbeat, returns `logoutSuccess`.
- Root `--logout`: client sends logout with no auth scope → `notLoggedIn` error return.
Where to read full syntax
All header directives, condition forms, same-frame rules, variables and pipes, lifecycle, `@loop` details, validate error codes, and normative runtime edge cases are in .dpws language reference. That reference is for people writing `.dpws` files—not DevPeek source internals.
Writing tips
- Start with the header and one login-success path with `~auth`; confirm scope and heartbeat, then add logout and not-logged-in branches.
- App `--type=ping` is not protocol Ping; if you cut upstream, keep `# ping auto` (see the language reference).
- Align conditions with decrypted JSON from Capture; syntax details and full example sets are in the language reference.
WebSocket Mock changes the message sequence the client sees on a live connection. Use it only in owned or authorized test environments, and disable temporary rules when joint debugging ends.