目录

boostbeast-websocket-实例-

boost::beast websocket 实例

环境:ubuntu

1. 安装boost

sudo apt install -y libboost-all-dev

2. Server端

#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 端

#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. 编译

g++ server.cpp -o server
g++ client.cpp -o client

5. 运行

https://i-blog.csdnimg.cn/direct/052ff9e7eca8482cb87acbce56e68c43.png

https://i-blog.csdnimg.cn/direct/2f0919be4a3649468fe36ee08f3c8d44.png