Minimal Node.js project to measure handshake performance and reliability when establishing many concurrent Azure OpenAI Realtime (WebRTC) data channel sessions.
| UI (gpt-4o-realtime-preview RPM: 36) |
|---|
![]() |
- Repeatedly creates WebRTC peer connections against the Azure Realtime endpoint.
- Measures time from start until DataChannel
open(handshake time). - Aggregates metrics (success / failure / p95 / last 10) and streams them to a small browser dashboard via Server‑Sent Events (SSE).
- Lets you ramp up connections in batches (ramp step + interval + per‑connection spacing + optional jitter).
Browser (dashboard) <--SSE / HTTP--> Express Server --(HTTP + WebRTC signaling)--> Azure OpenAI Realtime
Key files:
server.jsExpress API + ramp logicwebrtcSession.jsCreates one WebRTC session (ephemeral key -> SDP offer/answer -> DataChannel)metrics.jsSimple aggregatorpublic/index.htmlDashboard UI
| Method | Path | Description |
|---|---|---|
| POST | /start | Begin a run (JSON body with parameters) |
| POST | /stop | Stop and close all active connections |
| GET | /events | SSE stream of metrics every second |
| GET | /status | One‑shot metrics JSON |
| GET | / | Dashboard page |
{
"target": 50, // total desired concurrent web socket connections
"rampStep": 20, // connections per batch
"rampIntervalMs": 5000, // wait between batches
"batchDelayMs": 200 // delay between spawns inside one batch
}Server side validation enforces: rampStep >= 1, rampIntervalMs >= 5000, batchDelayMs >= 200.
See .env.example for a template you can copy. Do NOT commit your real .env.
| Name | Required | Notes |
|---|---|---|
| AZURE_OPENAI_RESOURCE | yes | Resource name (without https://) |
| AZURE_OPENAI_KEY | yes | Resource API key (used to mint ephemeral key) |
| AZURE_OPENAI_DEPLOYMENT | yes | Deployment logical name (model) |
| AZURE_OPENAI_REGION | yes | Region for Realtime endpoint (e.g. swedencentral) |
| API_VERSION | yes | API version supporting realtime preview |
| DC_TIMEOUT_MS | no | DataChannel open timeout (default 8000) |
| VERBOSE_LOG | no | "true" for extra console logging |
| LAUNCH_JITTER_MS | no | Adds random 0..N ms before each spawn |
| PORT | no | HTTP port (default 3000) |
Example .env (do NOT commit):
AZURE_OPENAI_RESOURCE=myresource
AZURE_OPENAI_KEY=***
AZURE_OPENAI_DEPLOYMENT=gpt-realtime
AZURE_OPENAI_REGION=swedencentral
API_VERSION=2025-04-01-preview
DC_TIMEOUT_MS=8000
VERBOSE_LOG=false
LAUNCH_JITTER_MS=50
PORT=3000
- Clone repo and create
.envfrom the example above (or copy.env.example). - Install deps:
npm install
- Run server:
node server.js
- Open http://localhost:3000 in a browser, adjust parameters, press Start.
- Watch metrics update live. Press Stop to terminate all connections.
- started: attempted connection count
- success: DataChannel opened
- failed: any error before open
- active: in‑flight attempts (started - success - failed)
- avgHandshakeMs / p95HandshakeMs: aggregate latency
- last10: last 10 (sorted) successful handshake times
- errors: map of error message -> occurrences
- Adds a silent audio track because the service requires an audio m-line.
- Uses ephemeral key pattern: long lived key only used server side to request short‑lived key.
- TURN not required for direct connectivity in this test scenario.
- No persistence of historical runs.
- No UI charting (only numbers) by default.
- No automatic backoff / retry logic.
MIT – see LICENSE.
Minimal, focused, and intentionally small for quick experimentation.
