WebSocket Class Reference

#include <Pt/Http/WebSocket.h>

Client handshake and messages on an upgraded stream. More...

Inherits Connectable.

Public Member Functions

 WebSocket (Client &client)
 Creates a WebSocket that handshakes through client.
 ~WebSocket ()
 Destructor.
void beginConnect (const std::string &url, const std::string &origin=std::string())
 Begins a client handshake for url.
Pt::Signal< WebSocket & > & connected ()
 Returns the signal emitted when the handshake finishes.
void endConnect ()
 Completes the client handshake.
WebSocketMessage & incoming ()
 Returns the incoming message.
WebSocketMessage & outgoing ()
 Returns the outgoing message.
void beginSend ()
 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 ping (const char *payload=0, std::size_t n=0)
 Enqueues a ping with an optional payload of at most 125 bytes.
void close (unsigned code=1000, const std::string &reason=std::string())
 Enqueues a close frame and ends the stream after the close handshake.
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.
Pt::Signal< WebSocket & > & inputReady ()
 Returns the signal emitted when data bytes were received.
Pt::Signal< WebSocket & > & outputReady ()
 Returns the signal emitted when data bytes were sent.
Pt::Signal< WebSocket & > & closed ()
 Returns the signal emitted when the stream ends.
void setTimeout (std::size_t timeout)
 Sets the stream timeout in milliseconds.
void setMaxMessageSize (std::size_t maxSize)
 Closes the stream when a data message exceeds maxSize.
void setIdleTimeout (std::size_t ms)
 Closes the stream after ms without a finished transfer.

Detailed Description

WebSocket is the client side of a WebSocket upgrade. It performs the HTTP handshake through an HTTP user agent and then sends and receives payloads on the stream that handshake produces. Host, port, event loop, timeout and TLS are settings of that agent. The socket stores a reference and does not own it, so the agent must outlive the socket, including a handshake that is still waiting on the loop. After a finished 101 the socket formats the stream the client already owns. The client still owns the connection. Closing the socket closes the stream. The socket does not own the stream. A client masks every frame it writes.

The example completes the handshake and then writes a text message.

void onOutputReady(Pt::Http::WebSocket& socket)
{
Pt::Http::MessageProgress progress = socket.endSend();
if( ! progress.finished() )
socket.beginSend();
}
void onInputReady(Pt::Http::WebSocket& socket)
{
if( ! progress.finished() )
{
socket.incoming().discard();
socket.beginReceive();
return;
}
socket.incoming().clear();
socket.beginReceive();
}
void onConnected(Pt::Http::WebSocket& socket)
{
socket.endConnect();
socket.outgoing().body() << "hello";
socket.beginSend();
socket.beginReceive();
}
void onClosed(Pt::Http::WebSocket& socket)
{
}
Pt::System::MainLoop loop;
Pt::Net::Endpoint ep("localhost", 80);
Pt::Http::Client client(loop, ep);
Pt::Http::WebSocket socket(client);
socket.connected() += Pt::slot(onConnected);
socket.outputReady() += Pt::slot(onOutputReady);
socket.inputReady() += Pt::slot(onInputReady);
socket.closed() += Pt::slot(onClosed);
socket.beginConnect("/ws");
loop.run();
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
@ Text
UTF-8 text.
Definition WebSocketMessage.h:80
void discard()
Drops the buffered body and leaves the type.
void setType(Type type)
Sets the data type of an outgoing message.
std::iostream & body()
Returns the payload stream.
Definition WebSocketMessage.h:97
void clear()
Drops the buffered body and sets the type to Unknown.
Client handshake and messages on an upgraded stream.
Definition WebSocket.h:133
void beginSend()
Begins sending outgoing().
void endConnect()
Completes the client handshake.
Pt::Signal< WebSocket & > & outputReady()
Returns the signal emitted when data bytes were sent.
Definition WebSocket.h:236
Pt::Signal< WebSocket & > & connected()
Returns the signal emitted when the handshake finishes.
Definition WebSocket.h:157
void beginReceive()
Begins receiving into incoming().
WebSocketMessage & outgoing()
Returns the outgoing message.
MessageProgress endReceive()
Completes the receive started by beginReceive().
Pt::Signal< WebSocket & > & inputReady()
Returns the signal emitted when data bytes were received.
Definition WebSocket.h:231
MessageProgress endSend()
Completes the send started by beginSend().
WebSocketMessage & incoming()
Returns the incoming message.
void beginConnect(const std::string &url, const std::string &origin=std::string())
Begins a client handshake for url.
Pt::Signal< WebSocket & > & closed()
Returns the signal emitted when the stream ends.
Definition WebSocket.h:247
ConstMethodSlot< R, ClassT, As... > slot(ClassT &object, R(BaseT::*method)(As...) const)
Returns a slot object for the given object/member pair.
Definition ConstMethod.h:172
void run()
Starts the loop.

Construct the socket with the Client that performs the handshake. Connect connected() and call beginConnect() with a request path, or with a ws:// URL whose host and port are already the client's endpoint. The path and query of that URL become the request URL; the client does not take the host from the URL. The optional second argument is the Origin header. endConnect() completes the handshake and throws if it failed. After that success the socket no longer uses the client for messages.

The socket owns two WebSocketMessage objects, incoming() and outgoing(), the way a client owns a request and a reply. Set the type, write the body, and call beginSend(). outputReady() reports that data bytes were sent. endSend() returns MessageProgress. If the send is not finished, beginSend() continues the same message. beginReceive() fills incoming(). inputReady() reports that data bytes were received. endReceive() returns progress. After finished(), clear() drops the body so the same object can carry the next message.

Ping, pong and close are socket operations, not messages.

socket.ping();
socket.close(1000, "done");
void ping(const char *payload=0, std::size_t n=0)
Enqueues a ping with an optional payload of at most 125 bytes.
void close(unsigned code=1000, const std::string &reason=std::string())
Enqueues a close frame and ends the stream after the close handshake.

ping() enqueues a ping. A received ping is answered by the engine. A received pong is consumed. Neither is delivered through incoming(). close() enqueues a close frame with a status code and a reason. A received close is answered by the engine. closeCode() and closeReason() report the handshake that ended the stream. closed() is emitted while this socket is still alive. The stream has already cleared its session pointer. Peer close, an I/O error, a close frame and destruction of the stream all emit it. It ends an outstanding send or receive. The owner deletes this socket.

On the server the application does not construct this type. The server facade is WebSocketSession, which exposes the same message operations without a client handshake.

Constructor & Destructor Documentation

◆ WebSocket()

WebSocket ( Client & client)
explicit

Stores a reference to client. The client must outlive this socket.

Member Function Documentation

◆ beginConnect()

void beginConnect ( const std::string & url,
const std::string & origin = std::string() )

url is a request path, or a ws:// URL whose host and port are the client's endpoint. origin is the Origin header. Host, port and TLS come from the client.

◆ endConnect()

void endConnect ( )
Exceptions
%std::exceptionif the handshake failed.

◆ beginSend()

void beginSend ( )
Exceptions
%std::logic_errorif a send is outstanding, the handshake is not finished, or a close is queued.
%std::invalid_argumentif the type is Unknown, the body is larger than setMaxMessageSize(), or a text body is not valid UTF-8.

◆ endSend()

MessageProgress endSend ( )
Returns
Progress of this send step.

◆ beginReceive()

void beginReceive ( )
Exceptions
%std::logic_errorif a receive is outstanding, the handshake is not finished, or the stream has ended.

◆ endReceive()

MessageProgress endReceive ( )
Returns
Progress of this receive step.

◆ ping()

void ping ( const char * payload = 0,
std::size_t n = 0 )
Exceptions
%std::invalid_argumentif n is greater than 125.
%std::logic_errorif the handshake is not finished.

◆ close()

void close ( 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 the handshake is not finished or a close is already queued.

◆ closed()

Pt::Signal< WebSocket & > & closed ( )

Emitted while this socket is still alive. The stream has already cleared its session pointer. Peer close, an I/O error, a close frame and destruction of the stream all emit it. The owner deletes this socket. Ends an outstanding send or receive.

◆ setTimeout()

void setTimeout ( std::size_t timeout)

The handshake timeout is Client::setTimeout().

◆ setMaxMessageSize()

void setMaxMessageSize ( std::size_t maxSize)

Zero disables the limit. The count is the declared payload of one data message from the first data opcode to FIN.

◆ setIdleTimeout()

void setIdleTimeout ( std::size_t ms)

Zero disables the idle timeout. A finished send or receive restarts it. A received ping or pong restarts it.