http_socket
The http_socket library is the first transport-aware layer on top of
the http_client_core, http_server, and sockets libraries. It
uses TCP sockets for connection management while delegating HTTP message
framing and connection semantics to the existing stream core and server
layers.
This library can be used with backend Prolog systems that support
unbound integer arithmetic and the sockets library: ECLiPSe, SICStus
Prolog, SWI-Prolog, Trealla Prolog, and XVM.
API documentation
Open the ../../apis/library_index.html#http_socket link in a web browser.
Loading
To load the library, load the loader.lgt file:
| ?- logtalk_load(http_socket(loader)).
Testing
To test this library, load the tester.lgt file:
| ?- logtalk_load(http_socket(tester)).
Current scope
The current implementation provides nineteen public predicates, grouped by responsibility:
Listener lifecycle:
open_listener/4,close_listener/1, andrequest_listener_shutdown/1.Reusable client connections:
open_connection/4,close_connection/1,connection_streams/3,exchange/3,exchange_connection/3,exchange/4, andexchange_connection/4.Managed connection pools:
open_connection_pool/4,close_connection_pool/1, andconnection_pool_stats/2.Server-side request serving:
serve_once/3,serve_websocket_once/5,serve_listener/4, andserve_listener/5.Open-ended serving control:
serve_until_shutdown/4,serve_until_shutdown/5, andrequest_shutdown/1.
Although it exposes these transport-oriented helpers, the library stays
focused on socket-backed connection and listener management. It
delegates HTTP message framing and connection semantics to
http_client_core and http_server, and delegates socket creation
and teardown to the sockets library.
Reusable client connections are represented by
http_connection(Host, Port, ...) handle terms that carry normalized
endpoint metadata and can be passed to exchange/3,
exchange_connection/3, connection_streams/3, and
close_connection/1.
Accepted WebSocket upgrades are represented by
http_websocket_connection(ClientInfo, Input, Output) handle terms
that can be passed to connection_streams/3 and
close_connection/1.
Managed connection pools are represented by
http_connection_pool(Host, Port, ...) handle terms that carry
normalized endpoint metadata and can be passed to exchange/3,
exchange_connection/3, close_connection_pool/1, and
connection_pool_stats/2.
Open-ended serving is controlled by a user-supplied control term. A
control term is any fresh non-variable term chosen by the caller to
identify one active serve_until_shutdown/4 or
serve_until_shutdown/5 loop. The same term is later passed to
request_shutdown/1 to stop that specific serving loop,
distinguishing it from any other listener loops running at the same
time.
The open_connection_pool/4 predicate supports the following options:
min_size(N)pre-opensNreusable connections when the pool is created. The default is0.max_size(N)limits the pool to at mostNmanaged connections. The default is10.connection_options(Options)passes socket options through toopen_connection/4when creating pooled connections.
Pool exchanges fail immediately with
resource_error(http_socket_connection_pool) when no pooled
connection is available and the pool is already at its maximum size.
The serve_listener/5 predicate supports the following option
families:
Shutdown options:
shutdown(keep_open)leaves the listener open after the bounded serving loop. This is the default.shutdown(close)closes the listener when the bounded serving loop finishes or aborts.
Worker options:
workers(serial)serves accepted connections sequentially in the caller thread. This is the default.workers(per_connection)spawns one worker thread per accepted connection and waits for all workers before returning.workers(pool(N))serves accepted connections in batches of up toNworker threads, waiting for each batch to finish before accepting the next batch.workers(pool(N, rolling))keeps up toNworker threads active and accepts the next connection as soon as one worker finishes.
Calling request_listener_shutdown/1 for a listener with an active
bounded serve_listener/5 loop wakes any blocked accept call and lets
the loop return with the client information terms accepted before the
shutdown request.
The serve_until_shutdown/4 and serve_until_shutdown/5 predicates
support the workers/1 option family:
workers(serial)serves accepted connections sequentially in the caller thread. This is the default.workers(per_connection)spawns one worker thread per accepted connection and waits for active workers when shutdown is requested.workers(pool(N))serves accepted connections using at mostNconcurrent worker threads, waiting for worker completion notifications before accepting additional connections.workers(pool(N, rolling))is accepted as an explicit alias for the rolling fixed-size worker-pool policy used byworkers(pool(N)).
Open-ended serving loops should use a fresh control term for each call
to serve_until_shutdown/4 or serve_until_shutdown/5.
When the same listener, serving, or pool-management option is given multiple times, the first occurrence is used.
WebSocket handshake workflow
The current WebSocket transport workflow is intentionally limited to the opening handshake handoff:
Client-side code can use
http_client::open_websocket/4to obtain a reusable upgraded connection handle.Server-side code can use
serve_websocket_once/5with a handler that builds a valid101 Switching Protocolsresponse, typically viahttp_server::accept_websocket/3.When the opening handshake succeeds, the returned upgraded connection remains open and its streams are available through
connection_streams/3for use withhttp_websocket::read_frame/2andhttp_websocket::write_frame/2or, at the next abstraction level, withhttp_websocket_messages::read_message/2andhttp_websocket_messages::write_message/2, or with the statefulhttp_websocket_sessionlayer when interleaved control frames and role-aware masking policies matter, including automatic close replies and optional automatic pong replies, or with thehttp_websocket_servicelayer, which provides the higher-levelrun_session/3-4callback loop that takes ownership of the upgraded connection and closes it automatically after the close handshake completes, the client-sidehttp_websocket_client_service::open/4-5convenience, and the server-sidehttp_websocket_server_service::serve_once/6-7convenience.Rejected or malformed handshakes are written to the peer and then reported as errors by
serve_websocket_once/5; the accepted streams are closed in that case.
Current limitations
Availability depends on the supported backends of the
socketslibrary.The library does not provide TLS or URL-based request helpers.
The WebSocket transport helper is limited to the opening handshake and upgraded connection handle management. It does not provide frame parsing, message I/O, or higher-level session handling.
The
workers(per_connection)andworkers(pool(N))options depend on backend thread support.Server-side helpers do not provide supervision trees.