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. 运行

相关推荐
pitt19973 小时前
NexLM 开源系列】让 AI 聊天更丝滑:WebSocket 实现流式对话!
websocket·chatgpt·deepseek·see·大模型集成·流式对话
无人不xiao14 小时前
WebSocket
网络·websocket·网络协议
web1376560764320 小时前
Spring Boot整合WebSocket
spring boot·后端·websocket
写完这行代码打球去1 天前
为什么大模型网站使用 SSE 而不是 WebSocket?
网络·websocket·网络协议
vvilkim3 天前
WebSocket:实现实时通信的利器
网络·websocket·网络协议
木头没有瓜3 天前
使用websocket,注入依赖service的bean为null
网络·websocket·网络协议
hamburgerDaddy13 天前
从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(十二) socketio 消息处理
前端·javascript·websocket·mongodb·react.js·node.js·express
忍者算法3 天前
在 Linux 下,服务器如何知道某个 TCP 连接来了消息? 这就涉及 IO 事件通知机制!
websocket·网络协议·tcp/ip·http·信息与通信
简单点了4 天前
基于websocket搭建聊天室
网络·websocket·网络协议