WebSocket Transport Architecture |
![]() |
Net4j WS 2 separates the stable Net4j transport machinery from the provider that performs WebSocket I/O. This article describes the division of responsibilities and the connection flow for developers integrating or diagnosing the transport. Practical server and client deployment belongs to the Operator's Guide.
Table of Contents
The org.eclipse.net4j.ws bundle provides WS/WSS acceptor and connector factories, route descriptions,
and Net4j connector integration. It does not depend on Jetty. The default jdk message-connection provider
is registered from the core bundle and implements the client side with the JDK HTTP/WebSocket APIs. The optional
org.eclipse.net4j.ws.jetty.server bundle adapts application-owned Jetty 12 servers.
A provider is selected from the org.eclipse.net4j.messageConnections factory product group. WS and WSS
connector factories look up that provider in their owning managed container, using the configured provider type or
the default type jdk.
A client IWSConnector represents an outgoing Net4j connection and uses a service URI plus a named
acceptor route. The server-side IWSAcceptor receives the message connection after the server integration
completes the HTTP upgrade. Acceptors apply their Net4j transport configuration and create server-side Net4j
connectors; they do not own the HTTP server.
WS uses a ws URI and acceptor type; WSS uses a wss URI and WSS acceptor type. The scheme and
factory type must agree. WSS TLS configuration remains in the selected client provider and server integration.
A provider factory creates one fresh IMessageConnection for each Net4j connector. It provides asynchronous
transport operations: start with a listener, send one complete framed buffer, request inbound messages, close
gracefully, or abort. The factory can hold shared client configuration; the returned connection has independent
runtime state and is not started until its Net4j connector activates.
The provider owns the WebSocket handshake and maps complete binary WebSocket messages to complete Net4j frames. A WebSocket message is not a Net4j channel buffer. The message connector owns Net4j framing, channel multiplexing, scheduling, control-channel processing, negotiation, and buffer lifecycle. The provider must preserve the complete frame payload and honor the buffer ownership callbacks.
The client connector factory parses the endpoint, route, optional cookies, and provider token. It asks the selected message-connection factory for a deferred connection and binds it to the Net4j connector. Connector activation starts the provider connection and its asynchronous handshake. When the transport is ready, the message connector runs the Net4j control and negotiation exchanges; application channels become usable after negotiation succeeds.
Outbound Net4j buffers are framed by the message connector and submitted through the provider send contract. Inbound complete frames are parsed by the connector and routed to channels. The provider does not choose Net4j channels or interpret application protocols.
Each accepted provider send has exactly one terminal callback. While the provider owns a submitted buffer, it must not mutate or reuse its storage; the callback marks the point after which provider access has ended. A rejected send must not retain the buffer or call the callback. During receive, demand is expressed in complete messages; the provider must deliver in order and retain each supplied storage lease until its release action runs.
The connector schedules buffer work and applies Net4j receive demand independently of WebSocket library scheduling. Provider implementations must not block indefinitely in abort and must complete accepted sends even during shutdown. These rules allow Net4j to keep channel and buffer semantics stable across providers.
The client provider owns its HttpClient configuration and WebSocket instance. A factory configured with a
caller-supplied client does not own or close that client. The embedding application controls its lifetime.
On the server, JettyWSUtil creates only an upgrade handler and routes it to the acceptors passed to the
call. The application owns Jetty's server, connectors, TLS setup, handler tree, and lifecycle. Other server integrations
may use different routing arrangements while still supplying an IMessageConnection to the acceptor.
See Deploying WebSocket Servers for Jetty deployment, Configuring WebSocket Clients for client configuration, and Securing WebSocket Transports for TLS.