WebSocket++ Documentation

repository·master·Indexed 27 days ago

https://github.com/zaphoyd/websocketpp

A header-only C++ library for implementing the RFC6455 WebSocket protocol for both client and server roles. It features a message/event-based interface, support for secure WebSockets (TLS), IPv6, and explicit proxies. The library is thread-safe and portable across Posix/Windows, supporting interchangeable network transport modules including Asio (Boost or standalone), C++ iostreams, and raw char buffers.

Tokens
4.9K
Snippets
5
Records
25
Agent score
91%

What's inside WebSocket++

  1. Overview of WebSocket++

    master
    WebSocket++ is a header-only C++ library that implements the RFC6455 WebSocket Protocol. It provides both client and server functionality and is designed to be integrated into existing C++ programs. The library is thread-safe and portable across Posix/Windows, 32/64bit, and various architectures (Intel/ARM/PPC).
  2. Understand WebSocket++ core control flow

    master

    WebSocket++ operates using a handshake followed by two independent asynchronous strands:

    1. Handshake

    • Uses information from endpoint::connect to construct a request.
    • The transport policy handles the byte transmission.
    • Upon receiving a response, the library validates it against RFC6455. If valid, the open handler is called.

    2. Read Strand (Incoming)

    • Reads bytes from the transport.
    • Dispatches complete messages to registered handlers: message_handler (for data) or ping/pong/close handlers (for control messages).
    • If no handler is registered for a control message, it is ignored.

    3. Write Strand (Outgoing)

    • Waits for application messages.
    • Performs error checking and frames messages per RFC6455.
    • Queues messages and passes them to the transport policy for output.

    Important: Handlers run in line with library processing. If you call send from inside a handler, the message may not be written to the socket until that handler returns. For high-frequency sending, consider using multiple threads or the built-in timer/interrupt functionality.

  3. Understand WebSocket++ Endpoint and Connection roles

    master

    WebSocket++ uses two primary object types:

    1. Endpoint: Responsible for creating and launching new connections, maintaining default settings, and managing shared network resources.
      • Note: Once a connection is launched, there is no link between the endpoint and the connection. Default settings are copied to the connection at launch. Changing endpoint settings only affects future connections.
      • Note: Endpoints do not maintain a list of outstanding connections; the application must manage this itself if needed.
    2. Connection: Stores information specific to an individual WebSocket session.

    Endpoints are created by combining an endpoint role (e.g., websocketpp::client or websocketpp::server) with an endpoint config (a template parameter struct that defines compile-time properties and dependencies).

  4. Initialize an Asio Endpoint in Perpetual Mode

    master

    When using an Asio-based configuration, you can initialize the transport system and set the endpoint to perpetual mode. In perpetual mode, the endpoint's processing loop will not exit automatically when there are no active connections, allowing it to wait for new connection requests.

    Steps:

    1. Call init_asio() to initialize the underlying transport.
    2. Call start_perpetual() to keep the loop running.
    3. Run the endpoint's run method in a background thread to process connection tasks (reading/delivering messages, framing, etc.) without blocking the main thread.
    // Setup logging (example: silent)
    m_endpoint.clear_access_channels(websocketpp::log::alevel::all);
    m_endpoint.clear_error_channels(websocketpp::log::elevel::all);
    
    // Initialize Asio transport
    m_endpoint.init_asio();
    m_endpoint.start_perpetual();
    
    // Run the endpoint in a background thread
    m_thread.reset(new websocketpp::lib::thread(&client::run, &m_endpoint));
  5. Implement a real-time WebSocket chat server

    master

    This tutorial provides a guide for implementing a real-time WebSocket chat server using WebSocket++. The implementation covers several key features including:

    • Nicknames: Managing user identities within the chat.
    • Channels: Implementing segmented communication rooms.
    • Subprotocol: Using WebSocket subprotocols for application-level logic.
    • Origin restrictions: Securing the server by restricting which origins can connect.
    • HTTP statistics page: Serving an HTTP page to display server statistics alongside the WebSocket service.
  6. Configure WebSocket++ network transports

    master

    WebSocket++ uses interchangeable network transport modules. You can choose a transport based on your project's requirements:

    • Asio: Uses either Boost.Asio or standalone Asio (recommended for high performance).
    • C++ iostreams: Uses standard C++ iostreams.
    • Raw char buffers: Uses raw buffers.
    • Custom: You can implement and write additional transport policies to support other networking or event libraries.
  7. Initialize a WebSocket++ Server with Asio

    master

    To create a basic WebSocket++ server, combine an endpoint role (e.g., websocketpp::server) with a configuration template (e.g., websocketpp::config::asio).

    Key initialization steps:

    1. Configure Logging: Use set_error_channels and set_access_channels to control verbosity. Use bitwise operators (like ^) to exclude specific channels like frame_payload.
    2. Initialize Transport: Call init_asio() to initialize the underlying Asio transport. If you have an existing io_service you wish to use, pass it as an argument to init_asio().
    3. Start the Server:
      • listen(port): Sets the port to listen on.
      • start_accept(): Queues a connection accept operation.
      • run(): Starts the Asio event loop. This call blocks until the endpoint is stopped.
    #define ASIO_STANDALONE
    
    #include <websocketpp/config/asio_no_tls.hpp>
    #include <websocketpp/server.hpp>
    #include <functional>
    
    typedef websocketpp::server<websocketpp::config::asio> server;
    
    class utility_server {
    public:
        utility_server() {
            // Set logging settings
            m_endpoint.set_error_channels(websocketpp::log::elevel::all);
            m_endpoint.set_access_channels(websocketpp::log::alevel::all ^ websocketpp::log::alevel::frame_payload);
    
            // Initialize Asio
            m_endpoint.init_asio();
        }
    
        void run() {
            // Listen on port 9002
            m_endpoint.listen(9002);
    
            // Queues a connection accept operation
            m_endpoint.start_accept();
    
            // Start the Asio io_service run loop
            m_endpoint.run();
        }
    private:
        server m_endpoint;
    };
    
    int main() {
        utility_server s;
        s.run();
        return 0;
    }
  8. Configure a WebSocket++ Client with Asio

    master

    To create a client endpoint using boost::asio without TLS support, use the websocketpp::config::asio_client configuration with the websocketpp::client role. It is recommended to use a typedef for this type as it is used frequently.

    Dependencies:

    • You must include <websocketpp/config/asio_no_tls_client.hpp> and <websocketpp/client.hpp>.
    • You must link against the boost_system library.
    • Ensure WebSocket++ and Boost headers are in your include path.
    #include <websocketpp/config/asio_no_tls_client.hpp>
    #include <websocketpp/client.hpp>
    
    typedef websocketpp::client<websocketpp::config::asio_client> client;
  9. Build WebSocket++ with Asio (Standalone vs Boost)

    master

    WebSocket++ requires an Asio implementation. Depending on your environment, use one of the following two methods:

    Option 1: Standalone Asio

    Use the standalone version from think-async.com.

    • Requirement: Define ASIO_STANDALONE in your code.
    • Command:
    c++ -std=c++11 step1.cpp

    Option 2: Boost Asio

    Use the Asio version bundled with the Boost libraries.

    • Requirement: Link against the boost_system library.
    • Command:
    c++ -std=c++11 step1.cpp -lboost_system
  10. Build WebSocket++ Client with Clang or G++

    master

    Building a WebSocket++ client requires linking against Boost libraries depending on your C++ standard and environment.

    Clang (C++11):

    clang++ -std=c++0x -stdlib=libc++ step3.cpp -lboost_system -D_WEBSOCKETPP_CPP11_STL_

    Clang (C++98 & Boost):

    clang++ step3.cpp -lboost_system -lboost_random -lboost_thread

    G++ (C++11):

    g++ -std=c++0x step3.cpp -lboost_system -D_WEBSOCKETPP_CPP11_STL_

    G++ (C++98 & Boost):

    g++ step3.cpp -lboost_system -lboost_random -lboost_thread
  11. Bind member functions as handlers using bind

    master

    To use a class member function as a WebSocket++ handler, use websocketpp::lib::bind (or std::bind) to provide the necessary context, such as the object instance and any additional parameters.

    con->set_open_handler(websocketpp::lib::bind(
        &connection_metadata::on_open,
        metadata,                          // The object instance (metadata pointer)
        &m_endpoint,                      // Additional parameter passed to the handler
        websocketpp::lib::placeholders::_1 // Placeholder for the connection_hdl provided by the library
    ));

    In this example, on_open will be called with the arguments (metadata, &m_endpoint, hdl).

    con->set_open_handler(websocketpp::lib::bind(
        &connection_metadata::on_open,
        metadata,
        &m_endpoint,
        websocketpp::lib::placeholders::_1
    ));
  12. Send WebSocket messages

    master

    Messages are sent using the endpoint::send method. This method is thread-safe and can be called from any thread to queue a message for sending on a specific connection.

    To specify the message type, use the websocketpp::frame::opcode values:

    • websocketpp::frame::opcode::text: For UTF-8 text messages.
    • websocketpp::frame::opcode::binary: For raw binary data.

    There are three overloads for send to accommodate different error-handling scenarios (including exception-free variants that return an error_code).