Transport Websocket

AEP Transport Binding: WebSocket

> Status: draft. Part of the AEP 0.1 protocol specification.

Purpose

Define how AEP runs over WebSocket, supporting bidirectional event streams over TCP with optional TLS.

Connection

URI Scheme

ws://host:port/path
wss://host:port/path  (TLS)

Subprotocol

The WebSocket handshake must request the subprotocol aep-0.1:

GET /aep HTTP/1.1
Upgrade: websocket
Sec-WebSocket-Protocol: aep-0.1

The server must respond with Sec-WebSocket-Protocol: aep-0.1 on success.

Future protocol versions use distinct subprotocol strings (e.g., aep-0.2). The server may advertise supported versions, and the client selects one.

Connection Parameters

Path and query string may carry initialization parameters (e.g., ws://host/aep?session_id=sess_01). This is transport-level metadata and not part of the protocol envelope.

Framing

AspectSpecification
Frame typeText frames only (opcode 0x1)
Message formatOne complete JSON AEP event per message
EncodingUTF-8
Multi-frameNot used. Each event is a single text frame.
Control framesPing/Pong used for heartbeat (see below)

Session Lifecycle

WebSocket StateSession StateNotes
ConnectingCREATED
Open (after handshake)OPENED
After session.readyREADY
Close frame (1000)CLOSEDGraceful shutdown
Close frame (1001–1015)CLOSEDShutdown with reason
Connection errorERRORNetwork failure
Protocol error (1002)ERRORFraming or message error

Heartbeat

WebSocket Ping/Pong frames serve as the transport-level heartbeat:

Application-level session.heartbeat events are still sent over text frames and carry structured metadata. Transport-level Ping is a simpler, lower-overhead mechanism for keep-alive.

Reconnect and Cursor Recovery

A disconnected client may reconnect and resume the event stream from a cursor:

1. Client opens a new WebSocket connection. 2. Client sends session.opened with a new or existing session_id. 3. Client sends subscription.requested with from_cursor set to the last received cursor value. 4. Server replays events from the cursor position.

Cursor format is transport-specific. For WebSocket, the cursor is the event id plus a sequence number:

evt_01JZ0000000000000000000000:42

Close Codes

Standard WebSocket close codes are mapped to AEP semantics:

CodeMeaningAEP Mapping
1000Normal closuresession.closed with reason "normal"
1001Going awaysession.closed with reason "peer_disconnected"
1002Protocol errorsession.error with code protocol_error
1008Policy violationsession.error with code unauthorized
1011Internal errorsession.error with code internal_error

Implementation Notes