WebSocketService Class Referenceabstract

#include <Pt/Http/WebSocketService.h>

Mapped service and factory for WebSocket sessions. More...

Inherits Service, and Connectable.

Inherited by BasicWebSocketService< S, Alloc >.

Public Member Functions

 WebSocketService ()
 Default constructor.
 ~WebSocketService ()
 Destructor.
const std::vector< std::string > & protocols () const
 Returns accepted Sec-WebSocket-Protocol names in preference order.
void addProtocol (const std::string &name)
 Adds one accepted Sec-WebSocket-Protocol name.
void clearProtocols ()
 Drops every accepted protocol name.
std::size_t maxSockets () const
 Returns the maximum number of live sessions.
void setMaxSockets (std::size_t n)
 Sets the maximum number of live sessions.
std::size_t idleTimeout () const
 Returns the idle timeout in milliseconds.
void setIdleTimeout (std::size_t ms)
 Sets the idle timeout in milliseconds.
std::size_t pingInterval () const
 Returns the ping interval in milliseconds.
void setPingInterval (std::size_t ms)
 Sets the ping interval in milliseconds.
std::size_t pingTimeout () const
 Returns the ping timeout in milliseconds.
void setPingTimeout (std::size_t ms)
 Sets the ping timeout in milliseconds.
std::size_t closeTimeout () const
 Returns the close timeout in milliseconds.
void setCloseTimeout (std::size_t ms)
 Sets the close timeout in milliseconds.
std::size_t maxMessageSize () const
 Returns the maximum data message size in bytes.
void setMaxMessageSize (std::size_t n)
 Sets the maximum data message size in bytes.
bool hasServlet () const
 True when a servlet is attached.
std::size_t socketCount () const
 Returns the number of counted sessions.
WebSocketSession * getSession (Stream &stream, const Request &request, const Reply &reply)
 Creates a session and counts a non-null result.
void releaseSession (WebSocketSession *session)
 Releases a session created by getSession().
Responder * getResponder (const Request &)
 Creates a responder to handle request received by a server.
void releaseResponder (Responder *)
 Destroys a responder created by a server.

Protected Member Functions

virtual Responder * onGetResponder (const Request &)
 Creates the handshake responder.
virtual void onReleaseResponder (Responder *responder)
 Destroys the handshake responder.
virtual void onUpgrade (Stream &stream, const Request &request, const Reply &reply) final
 Accepts or declines the upgraded stream.
virtual WebSocketSession * onGetSession (Stream &stream, const Request &request, const Reply &reply)=0
 Creates the session for stream.
virtual void onReleaseSession (WebSocketSession *session)=0
 Destroys a session created by onGetSession().

Detailed Description

WebSocketService is the server-side factory. Map it with an HTTP servlet like any other service, so the handshake request reaches it. This service owns the endpoint policy and the allocator. A separate WebSocketServlet owns the live sessions. Destroy that servlet before this service. Its destruction releases every remaining session while the derived service is still fully constructed. This destructor does not release sessions. By then the derived destructor has already run, and the virtual release call and the allocator are gone. This service keeps a non-owning pointer to its one active servlet.

The example is the usual server setup. The mapping servlet and the session owner are different objects. The setters are endpoint policy of this service. They apply before a servlet is constructed.

EchoService service;
service.setMaxSockets(100);
service.setIdleTimeout(60000);
service.setMaxMessageSize(1 << 20);
Pt::Http::WebSocketServlet sockets(service);
Pt::Http::MapUrl mapUrl("/ws", service);
server.addServlet(mapUrl);
WebSocket service for one session type.
Definition WebSocketService.h:390
Maps requests to a service by URL.
Definition Servlet.h:147
void setMaxSockets(std::size_t n)
Sets the maximum number of live sessions.
Definition WebSocketService.h:182
Owner of the sessions one WebSocket service creates.
Definition WebSocketServlet.h:72

The handshake responder answers a WebSocket upgrade with 101, with 503 when no servlet is attached or the accepted-session limit is already reached, or with 404 when the request is not a WebSocket upgrade. The responder is released before the server opens the stream. It is not the session. addProtocol() names one Sec-WebSocket-Protocol value this endpoint accepts. Several calls name several values, in preference order. An empty list accepts the upgrade and selects no name. A non-empty list selects the first offered name that is also accepted, and a request that offers none of them is answered with 400. setMaxSockets(), setIdleTimeout(), setPingInterval(), setPingTimeout(), setCloseTimeout() and setMaxMessageSize() are endpoint policy of this service. They apply before a servlet is constructed. The handshake reads the session limit here. The session base copies the idle, ping-interval, ping and close timeouts and the data-message limit onto the connection before the derived constructor runs. A missing servlet is still 503 when maxSockets() is zero. One service has one active WebSocketServlet. Constructing a second servlet throws std::logic_error.

After a finished 101 the HTTP server keeps the connection and delivers the upgraded stream to this service. This class implements that delivery and asks the servlet to create a session through getSession() with the stream, the opening request, and the opening reply. getSession() calls onGetSession() and counts a non-null session. The session binds the stream in its constructor, which accepts the upgrade. A null session leaves the stream unbound, and the HTTP server closes it. A null return is not counted. No attached servlet is a 503 from the handshake. The null check here covers only the window after a finished 101 and before the stream is delivered.

BasicWebSocketService is this factory for one session type. Derive this class when the session type depends on the upgrade, or when the session constructor needs more than the service, the stream, and the opening reply.

Pt::Http::WebSocketSession* ChatService::onGetSession(
const Pt::Http::Request& request,
const Pt::Http::Reply& reply)
{
const char* user = request.header().get("X-User");
return new ChatSession(*this, stream, reply, _rooms,
user ? user : "");
}
void ChatService::onReleaseSession(Pt::Http::WebSocketSession* session)
{
delete session;
}
const char * get(const char *key) const
Returns a field value.
MessageHeader & header()
Returns the header of the message.
Definition Message.h:472
HTTP reply message.
Definition Reply.h:64
HTTP request message.
Definition Request.h:65
One HTTP stream on a connection.
Definition Stream.h:92
Server facade of one accepted WebSocket stream.
Definition WebSocketSession.h:157

getSession() is the factory call. It calls onGetSession() and counts a non-null session. releaseSession() calls onReleaseSession() and drops that count. onGetSession() creates the session and onReleaseSession() destroys it. The request argument is the opening request. The reply argument is the opening reply. Both are valid for that call. Copy any header the session must keep. The session does not store the request or the reply. The two methods must use the same allocator. A pool, or any other detach, lives in the derived service. Return null from onGetSession() to decline the upgrade. The servlet owns the live sessions only. This service owns the endpoint policy, the allocator, and the count of sessions getSession() returned and releaseSession() has not yet released. This service does not keep a session list. socketCount() is that count.

Constructor & Destructor Documentation

◆ ~WebSocketService()

Does not release sessions. The active WebSocketServlet releases them before this destructor runs.

Member Function Documentation

◆ addProtocol()

void addProtocol ( const std::string & name)

Names are matched in the order they were added. An empty list accepts the upgrade and selects no name.

Exceptions
%std::invalid_argumentif name is empty or is not a single protocol token.

◆ maxSockets()

std::size_t maxSockets ( ) const

Zero means no limit. This is endpoint policy of this service. It applies before a servlet is constructed.

◆ setMaxSockets()

void setMaxSockets ( std::size_t n)

A handshake above this limit is answered with 503. Zero means no limit. A missing servlet is still 503 when this limit is zero. This is endpoint policy of this service. It applies before a servlet is constructed.

◆ idleTimeout()

std::size_t idleTimeout ( ) const

Zero means the idle timeout is disabled. This is endpoint policy of this service. It applies before a servlet is constructed.

◆ setIdleTimeout()

void setIdleTimeout ( std::size_t ms)

An accepted socket is closed after ms without an incoming frame. Incoming data, a received ping, and a received pong restart it. Sending does not. Zero disables it. This is endpoint policy of this service. It applies before a servlet is constructed.

◆ pingInterval()

std::size_t pingInterval ( ) const

Zero means the engine does not write keepalive pings. This is endpoint policy of this service. It applies before a servlet is constructed.

◆ setPingInterval()

void setPingInterval ( std::size_t ms)

An accepted socket writes a keepalive ping after ms without an incoming frame. Incoming data, a received ping, and a received pong restart it. Sending does not. Zero disables it. This is endpoint policy of this service. It applies before a servlet is constructed.

◆ pingTimeout()

std::size_t pingTimeout ( ) const

Zero means an unanswered ping has no deadline. This is endpoint policy of this service. It applies before a servlet is constructed.

◆ setPingTimeout()

void setPingTimeout ( std::size_t ms)

An accepted socket is closed if a ping is unanswered for ms. The wait starts at beginPing() and at a keepalive ping. Zero disables it. This is endpoint policy of this service. It applies before a servlet is constructed.

◆ closeTimeout()

std::size_t closeTimeout ( ) const

Zero leaves a close handshake unbounded. The default is ten seconds. This is endpoint policy of this service. It applies before a servlet is constructed.

◆ setCloseTimeout()

void setCloseTimeout ( std::size_t ms)

An accepted socket is closed if a close handshake is unanswered for ms. Zero leaves the wait unbounded. The default is ten seconds. This is endpoint policy of this service. It applies before a servlet is constructed.

◆ maxMessageSize()

std::size_t maxMessageSize ( ) const

Zero means the limit is disabled. This is endpoint policy of this service. It applies before a servlet is constructed.

◆ setMaxMessageSize()

void setMaxMessageSize ( std::size_t n)

A larger data message closes the socket. Zero disables the limit. The count is the declared payload from the first data opcode to FIN. This is endpoint policy of this service. It applies before a servlet is constructed.

◆ hasServlet()

bool hasServlet ( ) const

A missing servlet is a separate state from a zero maxSockets().

◆ socketCount()

std::size_t socketCount ( ) const

A session is counted when getSession() returns it, and dropped when releaseSession() releases it. A null return is not counted. Zero is not a reached limit. A missing servlet is a separate state, read with hasServlet().

◆ getSession()

WebSocketSession * getSession ( Stream & stream,
const Request & request,
const Reply & reply )

Calls onGetSession(). request is the opening request and reply is the opening reply. Both are valid until this call returns. A null return declines the upgrade and is not counted.

◆ releaseSession()

void releaseSession ( WebSocketSession * session)

Calls onReleaseSession() and drops the count. A null session is ignored. Called while this service is still fully constructed.

◆ onUpgrade()

virtual void onUpgrade ( Stream & stream,
const Request & request,
const Reply & reply )
finalprotectedvirtual

Implemented by this class. A derived service uses onGetSession() instead.

Reimplemented from Service.

◆ onGetSession()

virtual WebSocketSession * onGetSession ( Stream & stream,
const Request & request,
const Reply & reply )
protectedpure virtual

Called by getSession(). The active WebSocketServlet owns a non-null result. request is the opening request and reply is the opening reply. Both are valid for this call. Copy any header the session must keep. Return null to decline the upgrade. A null return is not counted.

Implemented in BasicWebSocketService< S, Alloc >.

◆ onReleaseSession()

virtual void onReleaseSession ( WebSocketSession * session)
protectedpure virtual

Called by releaseSession() while this service is still fully constructed. The servlet has already removed the session from its list.

Implemented in BasicWebSocketService< S, Alloc >.