Skip to content

WebSocket++

WebSocket++ 是 C++ WebSocket 库,基于 Boost.Asio,支持服务端和客户端,适合实时通信应用。

安装

bash
vcpkg install websocketpp

# CMake
find_package(websocketpp REQUIRED)
target_link_libraries(myapp PRIVATE websocketpp::websocketpp Boost::system)

WebSocket 服务端

cpp
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <set>
#include <mutex>

using server_t = websocketpp::server<websocketpp::config::asio>;
using connection_hdl = websocketpp::connection_hdl;

class ChatServer {
    server_t server_;
    std::set<connection_hdl, std::owner_less<connection_hdl>> connections_;
    std::mutex mtx_;

public:
    ChatServer() {
        server_.init_asio();
        server_.set_open_handler([this](connection_hdl hdl) { on_open(hdl); });
        server_.set_close_handler([this](connection_hdl hdl) { on_close(hdl); });
        server_.set_message_handler(
            [this](connection_hdl hdl, server_t::message_ptr msg) {
                on_message(hdl, msg);
            });
        // 关闭日志(生产环境)
        server_.clear_access_channels(websocketpp::log::alevel::all);
    }

    void on_open(connection_hdl hdl) {
        std::lock_guard lock(mtx_);
        connections_.insert(hdl);
        std::cout << "新连接,当前连接数: " << connections_.size() << "\n";
    }

    void on_close(connection_hdl hdl) {
        std::lock_guard lock(mtx_);
        connections_.erase(hdl);
    }

    void on_message(connection_hdl hdl, server_t::message_ptr msg) {
        std::string payload = msg->get_payload();
        std::cout << "收到: " << payload << "\n";

        // 广播给所有连接
        std::lock_guard lock(mtx_);
        for (auto& conn : connections_) {
            try {
                server_.send(conn, payload, websocketpp::frame::opcode::text);
            } catch (...) {}
        }
    }

    void run(uint16_t port) {
        server_.listen(port);
        server_.start_accept();
        std::cout << "WebSocket 服务器启动: ws://localhost:" << port << "\n";
        server_.run();
    }
};

int main() {
    ChatServer server;
    server.run(9002);
}

WebSocket 客户端

cpp
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>

using client_t = websocketpp::client<websocketpp::config::asio_client>;

class WsClient {
    client_t client_;
    websocketpp::connection_hdl hdl_;

public:
    WsClient() {
        client_.init_asio();
        client_.clear_access_channels(websocketpp::log::alevel::all);

        client_.set_open_handler([this](websocketpp::connection_hdl hdl) {
            hdl_ = hdl;
            std::cout << "已连接\n";
            send("Hello, Server!");
        });

        client_.set_message_handler(
            [](websocketpp::connection_hdl,
               client_t::message_ptr msg) {
                std::cout << "收到: " << msg->get_payload() << "\n";
            });

        client_.set_close_handler([](websocketpp::connection_hdl) {
            std::cout << "连接关闭\n";
        });
    }

    void connect(const std::string& uri) {
        websocketpp::lib::error_code ec;
        auto conn = client_.get_connection(uri, ec);
        if (ec) throw std::runtime_error(ec.message());
        client_.connect(conn);
        client_.run();
    }

    void send(const std::string& msg) {
        client_.send(hdl_, msg, websocketpp::frame::opcode::text);
    }
};

int main() {
    WsClient client;
    client.connect("ws://localhost:9002");
}

TLS WebSocket(wss://)

cpp
#include <websocketpp/config/asio_tls.hpp>
#include <websocketpp/server.hpp>
#include <openssl/ssl.h>

using tls_server_t = websocketpp::server<websocketpp::config::asio_tls>;
using ssl_context_ptr = websocketpp::lib::shared_ptr<boost::asio::ssl::context>;

ssl_context_ptr on_tls_init() {
    auto ctx = std::make_shared<boost::asio::ssl::context>(
        boost::asio::ssl::context::tlsv12);
    ctx->use_certificate_chain_file("server.crt");
    ctx->use_private_key_file("server.key", boost::asio::ssl::context::pem);
    return ctx;
}

tls_server_t server;
server.set_tls_init_handler([](websocketpp::connection_hdl) {
    return on_tls_init();
});

关键认知

WebSocket++ 基于 Boost.Asio,性能优秀。连接管理用 std::set<connection_hdl, std::owner_less<>> 而非裸指针,owner_lessweak_ptr 的比较器。生产环境必须启用 TLS(wss://)。

系统学习 C++ 生态,深入底层架构