Server-Sent Events (SSE) and Streaming
mockd supports Server-Sent Events (SSE) and HTTP chunked transfer encoding for simulating streaming APIs like AI chat completions, real-time feeds, and large file downloads.
Quick Start
Section titled “Quick Start”Using CLI
Section titled “Using CLI”Create SSE mocks directly from the command line:
# Basic SSE with custom eventsmockd add --path /events --sse \ --sse-event 'connected:{"status":"ok"}' \ --sse-event 'update:{"count":1}' \ --sse-event 'update:{"count":2}' \ --sse-delay 500
# OpenAI-compatible streamingmockd add -m POST --path /v1/chat/completions --sse --sse-template openai-chat
# Notification stream templatemockd add --path /notifications --sse --sse-template notification-stream
# Infinite keepalive streammockd add --path /stream --sse \ --sse-event 'ping:{}' \ --sse-delay 1000 \ --sse-repeat 0
# SSE with keepalive pings every 15 secondsmockd add --path /long-poll --sse \ --sse-event 'data:{"value":1}' \ --sse-keepalive 15000CLI SSE Flags:
| Flag | Description | Default |
|---|---|---|
--sse | Enable SSE streaming | |
--sse-event | Event (type:data), repeatable | |
--sse-delay | Delay between events (ms) | 100 |
--sse-template | Built-in template | |
--sse-repeat | Repeat count (0 = infinite) | 1 |
--sse-keepalive | Keepalive interval (ms) | 0 |
Using Configuration File
Section titled “Using Configuration File”{ "id": "basic-sse", "matcher": { "method": "GET", "path": "/events" }, "sse": { "events": [ { "data": "Hello" }, { "data": "World" } ], "timing": { "fixedDelay": 1000 } }}OpenAI-Compatible Streaming
Section titled “OpenAI-Compatible Streaming”{ "id": "openai-mock", "matcher": { "method": "POST", "path": "/v1/chat/completions" }, "sse": { "template": "openai-chat", "templateParams": { "tokens": ["Hello", "!", " How", " can", " I", " help", "?"], "model": "gpt-4", "finishReason": "stop", "includeDone": true, "delayPerToken": 50 } }}SSE Configuration
Section titled “SSE Configuration”Events
Section titled “Events”Define events to send to clients:
{ "sse": { "events": [ { "type": "message", "data": "Event payload", "id": "event-1", "retry": 3000 } ] }}| Field | Description |
|---|---|
type | Event type name (optional, for client filtering) |
data | Event payload (string or JSON object) |
id | Event ID (for Last-Event-ID resumption) |
retry | Reconnection interval in milliseconds |
comment | SSE comment (not delivered as event) |
Timing Control
Section titled “Timing Control”Control event delivery timing:
{ "sse": { "timing": { "initialDelay": 100, "fixedDelay": 500, "randomDelay": { "min": 100, "max": 500 }, "burst": { "count": 5, "interval": 10, "pause": 1000 }, "perEventDelays": [100, 200, 500] } }}| Field | Description |
|---|---|
initialDelay | Delay before first event (ms) |
fixedDelay | Constant delay between events (ms) |
randomDelay | Random delay range (min/max ms) |
burst | Send events in bursts (count/interval/pause in ms) |
perEventDelays | Specific delay for each event |
Lifecycle Management
Section titled “Lifecycle Management”Control connection behavior:
{ "sse": { "lifecycle": { "keepaliveInterval": 15, "timeout": 300, "maxEvents": 100, "connectionTimeout": 60, "termination": { "type": "graceful", "finalEvent": { "type": "close", "data": "Stream ended" }, "closeDelay": 0 } } }}| Field | Description |
|---|---|
keepaliveInterval | Keepalive ping interval (seconds, min 5) |
timeout | Connection timeout (seconds) |
maxEvents | Maximum events before closing |
connectionTimeout | Maximum stream duration (seconds) |
termination.type | Termination type: “graceful”, “abrupt”, “error” |
termination.finalEvent | Event to send on graceful close |
termination.closeDelay | Delay in ms before closing after final event |
Built-in Templates
Section titled “Built-in Templates”openai-chat
Section titled “openai-chat”OpenAI Chat Completions streaming format:
{ "sse": { "template": "openai-chat", "templateParams": { "tokens": ["Hello", " World"], "model": "gpt-4", "finishReason": "stop", "includeDone": true, "delayPerToken": 50 } }}notification-stream
Section titled “notification-stream”Real-time notification stream:
{ "sse": { "template": "notification-stream", "templateParams": { "notifications": [ { "type": "alert", "message": "System update" } ], "includeTimestamp": true, "includeId": true, "eventType": "notification" } }}Random Placeholders
Section titled “Random Placeholders”Use placeholders in event data for dynamic values:
| Placeholder | Description | Example |
|---|---|---|
$random:min:max | Random integer | $random:1:100 |
$uuid | UUID v4 | 550e8400-e29b-41d4-a716-446655440000 |
$timestamp | ISO 8601 timestamp | 2024-01-15T10:30:00Z |
$pick:a,b,c | Random choice | $pick:red,green,blue |
Example:
{ "data": { "id": "$uuid", "value": "$random:1:100", "status": "$pick:active,pending,complete", "timestamp": "$timestamp" }}HTTP Chunked Transfer
Section titled “HTTP Chunked Transfer”For non-SSE streaming (file downloads, NDJSON):
Basic Chunked Response
Section titled “Basic Chunked Response”{ "chunked": { "data": "Large content to stream in chunks...", "chunkSize": 1024, "chunkDelay": 100 }}NDJSON Streaming
Section titled “NDJSON Streaming”{ "chunked": { "format": "ndjson", "ndjsonItems": [ { "id": 1, "name": "Alice" }, { "id": 2, "name": "Bob" } ], "chunkDelay": 100 }}Admin API
Section titled “Admin API”List Connections
Section titled “List Connections”GET /sse/connectionsGet Connection
Section titled “Get Connection”GET /sse/connections/{id}Close Connection
Section titled “Close Connection”DELETE /sse/connections/{id}Get Stats
Section titled “Get Stats”GET /sse/statsMock-Specific Operations
Section titled “Mock-Specific Operations”GET /mocks/{id}/sse/connectionsDELETE /mocks/{id}/sse/connectionsGET /mocks/{id}/sse/bufferDELETE /mocks/{id}/sse/bufferTesting with curl
Section titled “Testing with curl”# Basic SSEcurl -N -H "Accept: text/event-stream" http://localhost:4280/events
# OpenAI streamingcurl -N -X POST \ -H "Content-Type: application/json" \ -H "Accept: text/event-stream" \ -d '{"stream": true, "messages": [{"role": "user", "content": "Hi"}]}' \ http://localhost:4280/v1/chat/completions
# Chunked downloadcurl -N http://localhost:4280/download/file
# NDJSON streamcurl -N http://localhost:4280/api/logs/streamBrowser EventSource
Section titled “Browser EventSource”const source = new EventSource('/events');
source.onmessage = (event) => { console.log('Message:', event.data);};
source.addEventListener('custom-type', (event) => { console.log('Custom event:', event.data);});
source.onerror = (error) => { console.error('Error:', error);};Next Steps
Section titled “Next Steps”- Stream Recording - Record SSE and WebSocket streams
- Response Templating - Dynamic response values
- Admin API - Manage SSE connections