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

    pong

Scope: 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.