Beast Logo

PrevUpHomeNext

Handshaking

A WebSocket session begins when one side sends the HTTP Upgrade request for websocket, and the other side sends an appropriate HTTP response indicating that the request was accepted and that the connection has been upgraded. The HTTP Upgrade request must include the Host HTTP field, and the URI of the resource to request. handshake is used to send the request with the required host and resource strings.

beast::websocket::stream<boost::asio::ip::tcp::socket> ws{ios};
...
ws.set_option(beast::websocket::keep_alive(true));
ws.handshake("ws.example.com:80", "/cgi-bin/bitcoin-prices");

The stream automatically handles receiving and processing the HTTP response to the handshake request. The call to handshake is successful if a HTTP response is received with the 101 "Switching Protocols" status code. On failure, an error is returned or an exception is thrown. Depending on the keep alive setting, the socket may remain open for a subsequent handshake attempt

Performing a handshake for an incoming websocket upgrade request operates similarly. If the handshake fails, an error is returned or exception thrown:

beast::websocket::stream<boost::asio::ip::tcp::socket> ws{ios};
...
ws.accept();

Servers that can handshake in multiple protocols may have already read data on the connection, or might have already received an entire HTTP request containing the upgrade request. Overloads of accept allow callers to pass in this additional buffered handshake data.

void do_accept(boost::asio::ip::tcp::socket& sock)
{
    boost::asio::streambuf sb;
    boost::asio::read_until(sock, sb, "\r\n\r\n");
    ...
    beast::websocket::stream<boost::asio::ip::tcp::socket&> ws{sock};
    ws.accept(sb.data());
    ...
}

Alternatively, the caller can pass an entire HTTP request if it was obtained elsewhere:

void do_accept(boost::asio::ip::tcp::socket& sock)
{
    boost::asio::streambuf sb;
    beast::http::request<http::empty_body> request;
    beast::http::read(sock, sb, request);
    if(beast::http::is_upgrade(request))
    {
        websocket::stream<ip::tcp::socket&> ws{sock};
        ws.accept(request);
        ...
    }
}

PrevUpHomeNext