You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何处理boost::beast::websocket的多async_write异步调用?

解决Boost.Beast WebSocket异步服务器多写冲突问题

核心问题是Boost.Beast的WebSocket异步操作不允许同时存在多个未完成的同类型操作(比如并发发起async_write),这会触发断言导致程序终止。strand仅能保证回调串行执行,但无法阻止你在已有写操作未完成时发起新的写请求,因此必须通过消息队列+串行触发的方式解决。

具体实现方案

给每个WebSocket会话添加消息队列,确保同一时间只有一个async_write在运行:

  1. 会话类增加成员
    为每个会话维护:

    • 一个消息队列(比如std::queue<std::string>或std::queue<boost::beast::flat_buffer>),缓冲待发送的消息
    • 绑定到WebSocket executor的strand,保证队列操作的线程安全
  2. 封装线程安全的发送接口
    提供公共的send方法,通过strand将消息投递到会话的io_context线程中处理,避免并发修改队列:

    void send(std::string msg) {
        boost::asio::post(ws_.get_executor(),
            boost::beast::bind_front_handler(
                &session::do_send,
                shared_from_this(),
                std::move(msg)));
    }
    
  3. 内部处理消息入队与写触发
    在strand上下文内将消息加入队列,若队列之前为空,则立即触发写操作:

    void do_send(std::string msg) {
        bool was_empty = write_queue_.empty();
        write_queue_.push(std::move(msg));
        if (was_empty) {
            do_write();
        }
    }
    
  4. 串行执行写操作
    实现do_write发起异步写,在回调中检查队列是否还有剩余消息,若有则继续触发下一次写:

    void do_write() {
        auto self(shared_from_this());
        boost::beast::websocket::async_write(
            ws_,
            boost::beast::buffer(write_queue_.front()),
            boost::asio::bind_executor(
                strand_,
                [self](boost::beast::error_code ec, std::size_t bytes_transferred) {
                    self->on_write(ec, bytes_transferred);
                }));
    }
    
    void on_write(boost::beast::error_code ec, std::size_t bytes_transferred) {
        boost::ignore_unused(bytes_transferred);
        if (ec) {
            return fail(ec, "write");
        }
    
        write_queue_.pop();
        if (!write_queue_.empty()) {
            do_write();
        }
    }
    

关键注意点

  • 所有对队列的操作必须在strand上下文内执行,避免多线程并发修改
  • 监听线程发送事件时,只需调用会话的send接口,无需直接操作WebSocket的写方法
  • Beast的WebSocket stream默认会自动响应ping/pong,若需主动发送ping,也需将ping操作加入队列或遵循串行执行规则

内容的提问来源于stack exchange,提问作者Ghasem Ramezani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 04:20:12