WSX Protocol

WebSocket extension protocol for genro-asgi.

Protocol

WSX protocol utilities.

WSX (WebSocket eXtended) is a protocol that brings HTTP-like semantics to WebSocket and NATS messaging. Messages are prefixed with WSX:// followed by JSON containing id, method, path, headers, cookies, query, data.

Format:

WSX://{“id”:”uuid”,”method”:”POST”,”path”:”/users”,”headers”:{},”data”:{}}

This module provides: - WSX_PREFIX: Protocol prefix constant - is_wsx_message(): Check if data is WSX format - parse_wsx_message(): Parse WSX message to dict - build_wsx_message(): Build WSX message from components - build_wsx_response(): Build WSX response message

Request handling uses MsgRequest from request.py which calls these functions.

genro_asgi.wsx.protocol.build_wsx_message(*, id, method, path='/', headers=None, cookies=None, query=None, data=None, tytx=False)[source]

Build a WSX request message string.

Parameters:
  • id (str) – Correlation ID (required)

  • method (str) – HTTP method (required)

  • path (str) – Request path (default: “/”)

  • headers (dict[str, str] | None) – Headers dict

  • cookies (dict[str, str] | None) – Cookies dict

  • query (dict[str, Any] | None) – Query parameters

  • data (Any) – Payload data

  • tytx (bool) – Whether to use TYTX serialization

Returns:

// prefixed message string

Return type:

str

genro_asgi.wsx.protocol.build_wsx_response(*, id, status=200, headers=None, cookies=None, data=None)[source]

Build a WSX response message string.

Parameters:
  • id (str) – Correlation ID from request (required)

  • status (int) – HTTP status code (default: 200)

  • headers (dict[str, str] | None) – Response headers dict

  • cookies (dict[str, Any] | None) – Response cookies dict

  • data (Any) – Response payload

Returns:

// prefixed response message string

Return type:

str

genro_asgi.wsx.protocol.is_wsx_message(data)[source]

Check if data is a WSX protocol message.

Parameters:

data (str | bytes) – String or bytes to check

Returns:

// prefix

Return type:

bool

genro_asgi.wsx.protocol.parse_wsx_message(data)[source]

Parse a WSX message into a dictionary.

Parameters:

data (str | bytes) – WSX message (with or without prefix)

Return type:

dict[str, Any]

Returns:

Parsed message dict with id, method, path, headers, etc.

Raises:

Handler

WSX handler — bridges WebSocket connections to the request/route/response cycle.

Accepts a WebSocket connection, authenticates via handshake headers, then enters a receive loop where each WSX message is demultiplexed on its first path segment to the target app and routed in that app’s own router.

Messages with path starting with _wsx/ are control messages (ping/pong, auth) handled inline and never routed.

class genro_asgi.wsx.handler.WsxHandler(server, max_concurrent=10)[source]

Bases: object

Handles WebSocket connections speaking the WSX protocol.

Each connection spawns a receive loop. Each WSX message becomes an independent request, demultiplexed to the target app and routed in that app’s own router. Messages are processed concurrently via asyncio tasks.

__init__(server, max_concurrent=10)[source]

Args: server: Parent AsgiServer instance. max_concurrent: Max concurrent WSX messages per connection.

max_concurrent
registry
server

Registry

Registry for active WSX WebSocket connections.

Tracks connected clients, supports lookup and broadcast.

class genro_asgi.wsx.registry.WsxConnectionInfo(connection_id, websocket, scope, auth=None)[source]

Bases: object

Metadata for a registered WSX connection.

__init__(connection_id, websocket, scope, auth=None)[source]

Args: connection_id: Unique identifier for this connection. websocket: Active WebSocket instance. scope: ASGI scope dict for this connection. auth: Authentication result dict (identity, tags), or None.

auth
property client: tuple[str, int] | None

Client address as (host, port).

connection_id
property identity: str | None

Authenticated user identity, if available.

scope
websocket
class genro_asgi.wsx.registry.WsxRegistry[source]

Bases: object

Registry of active WSX WebSocket connections.

async broadcast(data, *, exclude=None)[source]

Send a WSX response to all connected clients.

Parameters:
  • data (Any) – Payload to send.

  • exclude (str | None) – Connection ID to skip.

Return type:

int

Returns:

Number of clients the message was sent to.

find_by_identity(identity)[source]

Find all connections for a given authenticated identity.

Return type:

list[WsxConnectionInfo]

get(connection_id)[source]

Lookup connection by ID.

Return type:

WsxConnectionInfo | None

register(connection_id, websocket, scope, auth=None)[source]

Register a new WSX connection.

Return type:

WsxConnectionInfo

async send_to(identity, data)[source]

Send a WSX response to all connections of a given identity.

Return type:

int

Returns:

Number of clients the message was sent to.

unregister(connection_id)[source]

Unregister a WSX connection. Returns info if found.

Return type:

WsxConnectionInfo | None