C++ 上的 WebSocket:高级实时应用开发

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C++中的WebSocket:构建高性能实时应用程序



在现代Web开发世界中,实时交互已成为金融平台、在线游戏、监控系统和聊天应用的事实标准。如果您需要最高性能和最低延迟,C++仍然是无可替代的选择。在本文中,我们将探讨C++中WebSocket的高级技术,这些技术超越了简单的echo服务器。



我们将专注于能够处理数万个并发连接的架构解决方案,并使用流行的库分析具体的代码示例。



1. 库的选择与项目配置



对于C++的生产级开发,有两种主要方法:使用高级库uWebSockets (uWS) 或使用低级组合Boost.Asio + Boost.Beast。前者更简单,后者则提供完全控制。



Boost.Beast(基于Asio)是那些每一微秒都至关重要的项目的行业标准。让我们考虑一个异步WebSocket服务器的基本结构:



#include <boost/beast/core.hpp>#include <boost/beast/websocket.hpp>#include <boost/asio.hpp>#include <memory>#include <string>

namespace beast = boost::beast;namespace websocket = beast::websocket;namespace net = boost::asio;using tcp = net::ip::tcp;

// 用于处理单个连接的类class WebSocketSession : public std::enable_shared_from_this<WebSocketSession> { websocket::stream<beast::tcp_stream> ws_; beast::flat_buffer buffer_;public: explicit WebSocketSession(tcp::socket&& socket) : ws_(std::move(socket)) {}

void run() { // 异步接受WebSocket握手 ws_.async_accept( beast::bind_front_handler(&WebSocketSession::on_accept, shared_from_this())); }

void on_accept(beast::error_code ec) { if(!ec) { // 发送欢迎消息 ws_.async_write( net::buffer(std::string("欢迎来到实时世界!")), beast::bind_front_handler(&WebSocketSession::on_write, shared_from_this())); do_read(); } } // ... (续下文)};


关键点:每个客户端都获得自己的WebSocketSession实例,该实例以异步模式运行。这允许在等待数据时不阻塞主线程。



2. 带线程池的多线程服务器架构



单个io_context线程会受到CPU限制。为了扩展到数千个连接,请使用线程池。每个线程运行自己的io_context实例,连接通过accept负载均衡进行分配。



void run_server(const std::string& address, unsigned short port, int thread_count) {    net::io_context ioc{thread_count}; // 创建指定线程数的io_context

tcp::acceptor acceptor{ioc, {net::ip::make_address(address), port}};

// 在循环中启动accept std::function<void()> do_accept = [&]() { acceptor.async_accept( [&](beast::error_code ec, tcp::socket socket) { if (!ec) { // 创建会话并传递socket std::make_shared<WebSocketSession>(std::move(socket))->run(); } do_accept(); // 继续接受 }); }; do_accept();

// 启动线程池 std::vector<std::thread> threads; for (int i = 0; i < thread_count; ++i) { threads.emplace_back([&ioc]() { ioc.run(); }); }

for (auto& t : threads) t.join();}


重要

博客

书籍推荐