boost::beast websocket 实例

环境:ubuntu

1. 安装boost

bash 复制代码
sudo apt install -y libboost-all-dev

2. Server端

cpp 复制代码
#include <boost/asio.hpp>
#include <boost/beast.hpp>
#include <iostream>
#include <thread>

namespace beast = boost::beast; // 从 Boost.Beast 中导入命名空间
namespace websocket = beast::websocket;
namespace net = boost::asio;
using tcp = boost::asio::ip::tcp;

class WebSocketServer {
public:
    WebSocketServer(net::io_context& ioc, short port)
        : acceptor_(ioc, tcp::endpoint(tcp::v4(), port)), socket_(ioc) {}

    void start() {
        accept();
    }

private:
    void accept() {
        acceptor_.async_accept(socket_,
            [this](beast::error_code ec) {
                if (!ec) {
                    std::cout << "New connection established!" << std::endl;
                    handleWebSocket(std::move(socket_));
                }
                // 继续接收下一个连接
                accept();
            });
    }

    void handleWebSocket(tcp::socket socket) {
        try {
            // 创建 WebSocket 流并进行握手
            websocket::stream<tcp::socket> ws(std::move(socket));
            ws.accept();

            std::cout << "WebSocket handshake completed." << std::endl;

            beast::flat_buffer buffer;
            while (true) {
                // 读取消息
                ws.read(buffer);
                std::string message = beast::buffers_to_string(buffer.data());
                std::cout << "Received: " << message << std::endl;

                // 回显消息
                ws.write(net::buffer(message));

                // 清空缓冲区,准备接收下一条消息
                buffer.clear();
            }
        } catch (std::exception& e) {
            std::cerr << "WebSocket Error: " << e.what() << std::endl;
        }
    }

    tcp::acceptor acceptor_;
    tcp::socket socket_;
};

int main() {
    try {
        net::io_context ioc;

        short port = 8080; // 服务器端口
        WebSocketServer server(ioc, port);

        std::cout << "WebSocket server listening on port " << port << "..." << std::endl;

        // 启动服务器
        server.start();

        // 运行 IO 上下文
        ioc.run();
    } catch (std::exception& e) {
        std::cerr << "Server Error: " << e.what() << std::endl;
    }

    return 0;
}

代码解析

  1. WebSocketServer

    • 在构造函数中,设置服务器的监听端口(tcp::acceptor)。
    • start 方法启动 accept() 以异步接受新的连接。
    • 每个连接的 WebSocket 流通过 websocket::stream<tcp::socket> 来处理。
    • handleWebSocket 中,读取客户端发送的消息,回显给客户端。
  2. main 函数

    • 创建 net::io_context 对象,该对象是 Boost.Asio 的核心,用于管理异步操作。
    • 创建并启动 WebSocket 服务器,监听端口 8080
    • 调用 ioc.run() 来启动 IO 服务的事件循环,保持服务器运行。

运行效果

  • 服务器会监听 8080 端口。

  • 当客户端连接时,服务器接收客户端发送的消息并回显。

    例如,当客户端发送消息 "Hello from client 0" 时,服务器会接收到该消息并回传 "Hello from client 0"

3. Client 端

cpp 复制代码
#include <boost/asio.hpp>
#include <boost/beast.hpp>
#include <iostream>
#include <thread>
#include <vector>

namespace beast = boost::beast; // 从 Boost.Beast 中导入命名空间
namespace websocket = beast::websocket;
namespace net = boost::asio;
using tcp = boost::asio::ip::tcp;

class WebSocketClient {
public:
    WebSocketClient(net::io_context& ioc, const std::string& host, const std::string& port)
        : resolver_(ioc), ws_(ioc) {
        try {
            // 解析域名
            auto const results = resolver_.resolve(host, port);

            // 连接到 WebSocket 服务器
            net::connect(ws_.next_layer(), results.begin(), results.end());

            // 执行 WebSocket 握手
            ws_.handshake(host, "/");

            std::cout << "Connected to " << host << ":" << port << std::endl;
        } catch (std::exception& e) {
            std::cerr << "WebSocket Connection Error: " << e.what() << std::endl;
        }
    }

    void sendMessage(const std::string& message) {
        try {
            ws_.write(net::buffer(message));
            std::cout << "Sent: " << message << std::endl;

            beast::flat_buffer buffer;
            ws_.read(buffer);
            std::cout << "Received: " << beast::buffers_to_string(buffer.data()) << std::endl;
        } catch (std::exception& e) {
            std::cerr << "WebSocket Error: " << e.what() << std::endl;
        }
    }

private:
    tcp::resolver resolver_;
    websocket::stream<tcp::socket> ws_;
};

// 启动多个 WebSocket 客户端
void startClients(int num_clients, const std::string& host, const std::string& port) {
    net::io_context ioc;
    std::vector<std::thread> threads;

    for (int i = 0; i < num_clients; ++i) {
        threads.emplace_back([&, i] {
            WebSocketClient client(ioc, host, port);
            client.sendMessage("Hello from client " + std::to_string(i));
        });
    }

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

int main() {
    std::string host = "127.0.0.1";           // WebSocket 服务器地址
    std::string port = "8080";                  // WebSocket 服务器端口
    int num_clients = 5;                      // 需要并发的 WebSocket 连接数

    startClients(num_clients, host, port);

    return 0;
}

关键点

  • 使用 boost::asio::io_context 管理异步操作。
  • 每个 WebSocket 连接由一个独立线程维护。
  • 连接后发送消息并接收响应。

代码解析

  1. WebSocketClient

    • 解析服务器地址并连接 (resolver_.resolvenet::connect)。
    • 进行 WebSocket 握手 (ws_.handshake)。
    • 发送消息 (ws_.write) 并读取服务器响应 (ws_.read)。
  2. startClients 函数

    • 通过 std::vector<std::thread> 创建多个线程,每个线程都运行一个 WebSocket 客户端实例。
    • 每个客户端连接到服务器后,发送 Hello from client N 消息并等待响应。
  3. main 函数

    • 指定 WebSocket 服务器(默认使用 echo.websocket.org 进行回显测试)。
    • 启动 5 个并发 WebSocket 连接。

4. 编译

bash 复制代码
g++ server.cpp -o server
g++ client.cpp -o client

5. 运行

相关推荐
予昊5 小时前
从零实现“在线五子棋对战“:WebSocket 实时通信 + 段位匹配
java·开发语言·网络·websocket
隔窗听雨眠15 小时前
大模型实时通信协议深度对比:SSE、WebSocket与gRPC的选型指南与实战解析
网络·websocket·网络协议
艾莉丝努力练剑3 天前
【AI大模型接入SDK】WebSocket & SSE 协议
网络·c++·websocket·网络协议·学习·面试
虎王物联4 天前
PHP Swoole实现物联网MQTT数据订阅与WebSocket实时推送
物联网·mqtt·websocket·php·swoole
一条泥憨鱼6 天前
【从0开始学习计算机网络】| WebSocket-握手、全双工和心跳
websocket·计算机网络·网络安全·https·dns
GitLqr7 天前
从 TCP 底层看实时通信:为什么 SSE 往往比 WebSocket 更香?
websocket·http·openai
脉动数据行情17 天前
Python WebSocket 国内商品期货|螺纹钢 & 铁矿石实时行情监听
开发语言·python·websocket
宠友信息7 天前
内容社区源码开发实践解析,用Spring Boot打造1:1仿小红书源码平台
java·spring boot·redis·websocket·mysql·spring·uni-app
limingade9 天前
智能拨号器APP-外部WebSocket话单推送系统接口文档
网络·websocket·智能拨号器app·远程推送号码到手机拨打电话·手机app稳定长连接·手机拨打电话后推送话单和录音