Beast Logo



The interface to Beast's WebSocket implementation is a single template class beast::websocket::stream which wraps a "next layer" object. The next layer object must meet the requirements of SyncReadStream if synchronous operations are performed, or AsyncStream if asynchronous operations are performed, or both. Arguments supplied during construction are passed to next layer's constructor. Here we declare a websocket stream over a TCP/IP socket with ownership of the socket:

boost::asio::io_service ios;
beast::websocket::stream<boost::asio::ip::tcp::socket> ws{ios};
Using SSL

To use WebSockets over SSL, choose an SSL stream for the next layer template argument when constructing the stream.

#include <beast/websocket/ssl.hpp>
#include <beast/websocket.hpp>
#include <boost/asio/ssl.hpp>

boost::asio::io_service ios;
boost::asio::ssl::context ctx{boost::asio::ssl::context::sslv23};
beast::websocket::stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ws{ios, ctx};
[Note] Note

When creating websocket stream objects using SSL, it is necessary to include the file <beast/websocket/ssl.hpp>.

Non-owning references

For servers that can handshake in multiple protocols, it may be desired to wrap an object that already exists. This socket can be moved in:

boost::asio::ip::tcp::socket&& sock;
beast::websocket::stream<boost::asio::ip::tcp::socket> ws{std::move(sock)};

Or, the wrapper can be constructed with a non-owning reference. In this case, the caller is responsible for managing the lifetime of the underlying socket being wrapped:

boost::asio::ip::tcp::socket sock;
beast::websocket::stream<boost::asio::ip::tcp::socket&> ws{sock};

The layer being wrapped can be accessed through the websocket's "next layer", permitting callers to interact directly with its interface.

boost::asio::ssl::context ctx{boost::asio::ssl::context::sslv23};
beast::websocket::stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>> ws{ios, ctx};
ws.next_layer().shutdown(); // ssl::stream shutdown
[Warning] Warning

Initiating read and write operations on the next layer while stream operations are being performed can break invariants, and result in undefined behavior.