WebSocketSession Class Referenceabstract

#include <Pt/Http/WebSocketSession.h>

Server facade of one accepted WebSocket stream. More...

Inherits Connectable.

Public Member Functions

 WebSocketSession (WebSocketService &service, Stream &stream, const Reply &reply)
 Binds stream for service.
 ~WebSocketSession ()
 Closes the stream.
WebSocketService & service ()
 Returns the service that created this session.
const WebSocketService & service () const
 Returns the service that created this session.
const std::string & protocol () const
 Returns the protocol name selected on the 101.
WebSocketMessage & incoming ()
 Returns the incoming message.
WebSocketMessage & outgoing ()
 Returns the outgoing message.
void beginSend (bool finished=true)
 Begins sending outgoing().
MessageProgress endSend ()
 Completes the send started by beginSend().
void beginReceive ()
 Begins receiving into incoming().
MessageProgress endReceive ()
 Completes the receive started by beginReceive().
void beginPing (const char *payload=0, std::size_t n=0)
 Begins writing a ping with an optional payload of at most 125 bytes.
void endPing ()
 Completes the ping started by beginPing().
void beginShutdown (unsigned code=1000, const std::string &reason=std::string())
 Begins a close handshake.
void endShutdown ()
 Completes the shutdown started by beginShutdown().
void close ()
 Releases the stream and writes no frame.
unsigned closeCode () const
 Returns the close status code of the handshake that ended the stream.
const std::string & closeReason () const
 Returns the close reason of the handshake that ended the stream.

Protected Member Functions

virtual void onInput ()=0
 Called when data bytes were received.
virtual void onOutput ()=0
 Called when data bytes were sent.
virtual void onPingReady ()
 Reports that the ping operation completed.
virtual void onShutdownReady ()
 Reports that the shutdown operation completed.
virtual void onClosed ()
 Reports that the engine has ended the protocol.
virtual void onPong (const std::string &payload)
 Reports a received pong.

Detailed Description

WebSocketSession is the application object of one upgraded stream. Derive from it to keep the state that must survive from one message to the next: a subscription, a cursor, a user, or a reference into the application domain. The HTTP server already owns the connection and the stream. This session formats messages on that stream. It is not a channel bind the application performs, and it is not a request responder. The handshake responder has already been released when the session begins. A server does not mask the frames it writes.

The example starts a receive in the constructor and reads each payload from the input callback. Domain state belongs in the derived session.

class EchoSession : public Pt::Http::WebSocketSession
{
public:
const Pt::Http::Reply& reply)
: Pt::Http::WebSocketSession(service, stream, reply)
{
}
protected:
virtual void onInput()
{
if( ! progress.finished() )
{
return;
}
}
virtual void onOutput()
{
}
virtual void onClosed()
{
close();
}
};
Progress of an asynchronous HTTP send or receive.
Definition Message.h:337
bool finished() const
Returns true if message is complete.
Definition Message.h:373
HTTP reply message.
Definition Reply.h:64
One HTTP stream on a connection.
Definition Stream.h:92
void discard()
Drops the buffered body and leaves the type.
void clear()
Drops the buffered body and sets the type to Unknown.
Mapped service and factory for WebSocket sessions.
Definition WebSocketService.h:132
Server facade of one accepted WebSocket stream.
Definition WebSocketSession.h:157
WebSocketSession(WebSocketService &service, Stream &stream, const Reply &reply)
Binds stream for service.
virtual void onInput()=0
Called when data bytes were received.
virtual void onOutput()=0
Called when data bytes were sent.
void close()
Releases the stream and writes no frame.
WebSocketService & service()
Returns the service that created this session.
Definition WebSocketSession.h:185
virtual void onClosed()
Reports that the engine has ended the protocol.
void beginReceive()
Begins receiving into incoming().
MessageProgress endReceive()
Completes the receive started by beginReceive().
MessageProgress endSend()
Completes the send started by beginSend().
WebSocketMessage & incoming()
Returns the incoming message.
HTTP clients and servers.
Core module.
Definition Allocator.h:33

The service factory constructs the session with the service, with the stream of this upgrade, and with the opening reply. The reply is valid for the constructor call. The base constructor reads the selected subprotocol from that reply, binds the stream, and copies the service idle, ping-interval, ping and close timeouts and the data-message limit onto the connection. It does not store the reply. The derived constructor runs after that. Its members are initialized and the stream is open. Start the first beginReceive() or beginSend() there. There is no separate accept callback. By the time the derived constructor body runs, the base has already bound the stream.

incoming() and outgoing() are the two payloads. beginSend() writes outgoing(). Call beginSend(false) while more body will be written. beginReceive() reads into incoming(). onInput() runs when data bytes were received. Call endReceive(), read incoming() when progress reports body bytes, and start the next receive if the message is not finished. A ping does not run onInput(). A pong runs onPong() and does not change incoming(). onOutput() runs when data bytes were sent. Call endSend() and continue the send when progress is not finished. onClosed() runs when the engine has ended the protocol and no local shutdown is outstanding. Call close() from onClosed(), or from onShutdownReady() after endShutdown(), to release the session. close() from onClosed() destroys the session before that call returns. The servlet also releases remaining sessions when it is destroyed.

beginReceive() starts frame processing. Until then, incoming frames stay in the stream. Control frames are processed while a receive is outstanding. A local beginShutdown() also keeps input running until the peer replies with its close frame. The two are independent: a receive started before or during a shutdown still delivers what the peer sent before that reply.

protocol() is the single name the responder wrote as Sec-WebSocket-Protocol on the 101, or empty when none was selected. The base copies it from the opening reply before the derived constructor body runs. It is not the list the client offered. A reply that echoes more than one token, or a value that is not one protocol token, fails construction. The server then closes the stream. service() reaches state shared by every connection of this endpoint. The idle, ping-interval, ping and close timeouts and the data-message limit are copied from the WebSocketService before the derived constructor runs. Closing the session closes the stream. The session does not own the stream or the connection. The destructor closes the stream. A derived constructor that throws still runs this destructor, so a failed construction does not leave an accepted stream without an owner.

Ping, shutdown and close stay control operations on this type.

beginShutdown(1000, "done");
void beginPing(const char *payload=0, std::size_t n=0)
Begins writing a ping with an optional payload of at most 125 bytes.
void beginShutdown(unsigned code=1000, const std::string &reason=std::string())
Begins a close handshake.

beginPing() enqueues a ping. onPingReady() reports that its frame was written; call endPing() from that callback to observe a write error. A received ping is answered by the engine. After a close frame is queued nothing further is written, so beginPing() throws and a received ping is no longer answered. beginShutdown() enqueues a close frame and keeps reading until the peer replies. A peer that never starts a receive never replies, so the idle timeout copied from the WebSocketService is the only bound on that wait. onShutdownReady() reports the completed handshake; call endShutdown() from that callback to observe an error, then close(). close() releases the stream and writes no frame. The destructor unbinds the stream. beginSend() and beginReceive() then throw. No close frame leaves the code at 1006. closeCode() and closeReason() report the handshake that ended the stream.

Constructor & Destructor Documentation

◆ WebSocketSession()

WebSocketSession ( WebSocketService & service,
Stream & stream,
const Reply & reply )

The active WebSocketServlet owns this session. reply is the opening handshake reply and is valid for this call. The selected subprotocol is copied from it. The reply is not stored.

The idle, ping-interval, ping and close timeouts and the data-message limit are copied from service.

Exceptions
%std::runtime_errorif Sec-WebSocket-Protocol is not one protocol token.

Member Function Documentation

◆ protocol()

const std::string & protocol ( ) const

Empty when the opening reply selected no name.

◆ beginSend()

void beginSend ( bool finished = true)

The completion flag is true when this is the last part of the message. Call beginSend(false) while more body will be written.

Parameters
finishedTrue if this is the last part of the message.

◆ endSend()

MessageProgress endSend ( )
Returns
Progress of this send step.
Exceptions
%std::logic_errorif the send has not completed or the stream has ended.

◆ beginReceive()

void beginReceive ( )

Starts processing incoming frames. Frames received before this call stay in the stream.

Exceptions
%std::logic_errorif a receive is outstanding, or the stream has ended.
%std::exceptionif a protocol violation ended the frame stream, or a previous read failed.

◆ endReceive()

MessageProgress endReceive ( )
Returns
Progress of this receive step.
Exceptions
%std::logic_errorif the receive has not completed.
%std::exceptionif a protocol violation ended the frame stream, or a previous read failed.

◆ beginPing()

void beginPing ( const char * payload = 0,
std::size_t n = 0 )
Exceptions
%std::invalid_argumentif n is greater than 125, or if payload is null and n is nonzero.
%std::logic_errorif a ping is outstanding, a close is queued, or the stream has ended.

◆ endPing()

void endPing ( )
Exceptions
%std::logic_errorif the ping is not ready.
%std::exceptionif writing the ping failed.

◆ beginShutdown()

void beginShutdown ( unsigned code = 1000,
const std::string & reason = std::string() )
Exceptions
%std::invalid_argumentif code is 1005, 1006 or 1015, if reason is longer than 123 bytes, or if reason is not valid UTF-8.
%std::logic_errorif a shutdown is outstanding, or a close is already queued.

◆ endShutdown()

void endShutdown ( )
Exceptions
%std::logic_errorif the shutdown is not ready.
%std::exceptionif the close handshake failed.

◆ close()

void close ( )

Does not block and emits nothing. The servlet releases this session. beginSend() and beginReceive() then throw. No close frame leaves closeCode() at 1006.

◆ onPingReady()

virtual void onPingReady ( )
protectedvirtual

Call endPing() to observe a write error.

◆ onShutdownReady()

virtual void onShutdownReady ( )
protectedvirtual

The stream stays bound. Call endShutdown() to observe a close-handshake error, then close().

◆ onClosed()

virtual void onClosed ( )
protectedvirtual

No local shutdown is outstanding. The stream stays bound. Call close() to release the session. close() destroys the session before this call returns.

◆ onPong()

virtual void onPong ( const std::string & payload)
protectedvirtual

The payload contains arbitrary bytes and is valid for the duration of this call. A pong does not change incoming() or run onInput().