http_websocket_session

This library provides the next WebSocket slice on top of the http_websocket_messages library. It adds a state term for incremental reads, surfaces interleaved control messages while a fragmented text or binary message is still pending, applies role-aware client and server masking when writing messages, and can automatically orchestrate close replies and optional pong replies.

This library is a pure state-machine layer working on binary streams: it does not create threads and does not depend on socket support. The higher-level callback-driven session loops, keepalive and idle-timeout policies, and the registry-backed broadcast helpers for upgraded http_socket connections are provided by the http_websocket_service library.

This library can be used with backend Prolog systems that support unbound integer arithmetic.

API documentation

Open the ../../apis/library_index.html#http_websocket_session link in a web browser.

Loading

To load the library, load the loader.lgt file:

| ?- logtalk_load(http_websocket_session(loader)).

Testing

To test this library, load the tester.lgt file:

| ?- logtalk_load(http_websocket_session(tester)).

Current scope

The current implementation provides:

  • initial_state/1 and is_state/1 for working with session state terms.

  • read_message/4 for stateful message reads that preserve pending fragmented data across interleaved control messages while tracking close-handshake state.

  • read_message/5 for stateful message reads plus automatic close-handshake replies.

  • read_message/6 for stateful message reads plus automatic close-handshake replies and optional auto-pong and maximum payload length policies.

  • write_message/2-3 as stateless convenience wrappers for role-aware writes.

  • write_message/4-5 for role-aware writes that also update the session state, including close-handshake transitions.

Role-aware objects

The parameterized object http_websocket_session(Role, TextRepresentation) accepts:

  • Role equal to client or server

  • TextRepresentation equal to atom, chars, or codes

The library also provides two convenience objects using atom text:

  • http_websocket_client_session

  • http_websocket_server_session

Client sessions expect unmasked inbound frames and mask all outgoing frames. Server sessions expect masked inbound frames and leave outgoing frames unmasked.

Stateful reads

The read_message/4 predicate threads an explicit session state term:

read_message(Stream, State0, State, Message)

When a fragmented text or binary message is in progress and a control frame is received before the final continuation frame, the control frame is returned as a normalized message(Type, Payload) term and the pending fragmented data is kept in State for the next call.

Close-handshake state is tracked in the returned state. Open states keep the compact form session_state(Pending). Once a close message has been sent or received, the state uses session_state(Pending, CloseStatus) where CloseStatus is one of:

  • close_sent(Payload)

  • close_received(Payload)

  • closed(SentPayload, ReceivedPayload)

Automatic control handling

The read_message/5 predicate automatically writes a matching close reply when it reads a close message and the session state shows that no close message has yet been sent.

The read_message/6 predicate adds the options:

  • auto_pong(on) or auto_pong(off)

  • max_payload_length(Bytes)

When auto_pong(on) is used, incoming ping messages are still returned to the caller but a matching pong message is written automatically on the output stream. When max_payload_length(Bytes) is used, inbound frames whose declared payload length is greater than Bytes are rejected before allocating payload storage.

Outgoing fragmentation

The write_message/3 predicate accepts the option:

  • fragment_size(Size)

For text and binary messages, this splits the payload into frames of at most Size bytes. The first frame uses the original opcode and continuation frames use the continuation opcode. Control messages remain single final frames regardless of the option.

Current workflow

  • Complete the opening handshake with http_client::open_websocket/4 or http_socket::serve_websocket_once/5.

  • Use the http_websocket_messages layer when you only need stateless message normalization and simple reassembly.

  • Use the http_websocket_session layer when you need stateful reads across interleaved control messages, close-state tracking, automatic close replies, optional auto-pong behavior, or role-aware outgoing fragmentation and masking.

  • Use the http_websocket_service library when a callback object should own the connection lifecycle through higher-level session loops with optional keepalive, idle-timeout, and registry-backed broadcast policies.

Current limitations

  • Fragmentation is controlled only by fixed payload chunk size.

  • Reserved-bit extension negotiation and extension semantics remain delegated to lower layers.