c++如何实现websocket通信_c++ websocketpp库配置与服务端逻辑【实战】

发布时间 - 2026-01-07 00:00:00    点击率:
WebSocket在C++中无标准库支持,websocketpp是主流纯头文件方案;需正确配置Boost.Asio依赖、禁用permessage-deflate压缩、处理连接生命周期事件,并注意线程安全与广播机制。

WebSocket 在 C++ 中没有标准库支持,websocketpp 是目前最成熟、免依赖 Boost.Asio(可选)、纯头文件的主流方案。它不绑定具体网络后端,但默认推荐搭配 Boost.Asio 使用;若想零依赖,也可用 standalone Asio 替代,但需手动处理 TLS 和底层 socket 细节。

如何配置 websocketpp(CMake + Boost.Asio)

常见错误是只包含头文件却未链接 Boost.System 或漏定义宏,导致编译失败或运行时崩溃。

  • 确保安装了 boost(≥1.65),至少包含 boost_systemboost_thread
  • CMakeLists.txt 中必须添加:
    find_package(Boost REQUIRED COMPONENTS system thread)
    target_link_libraries(your_target PRIVATE Boost::system Boost::thread)
  • 在包含 websocketpp/config/asio_no_tls.hpp 前,定义 BOOST_ASIO_STANDALONE 会导致冲突,应避免;正确做法是直接使用 asio.hppasio_no_tls.hpp,并确保 BOOST_SYSTEM_DYN_LINK 宏与链接方式一致
  • 若用 MinGW 编译,需额外加 -DBOOST_THREAD_USE_LIB 防止 undefined reference to `boost::system::generic_category()`

写一个最小可用的服务端(echo server)

核心是继承 websocketpp::server 模板,并注册消息回调。注意:所有 handler 回调都运行在 IO 线程中,不可阻塞;如需耗时操作,必须 offload 到线程池。

  • 使用 websocketpp::config::asio(带 TLS 支持)或 asio_no_tls(纯 HTTP 协议)
  • set_message_handler 的 lambda 参数是 connection_hdlmessage_ptr,后者需用 get_payload() 提取字符串
  • 发送响应必须用 send(hdl, payload, opcode),其中 opcode 通常为 websocketpp::frame::opcode::text
  • 服务端启动前必须调用 listen()start_accept(),否则不会接收连接
#include 
#include 
#include 

typedef websocketpp::server server;

int main() { server s; s.init_asio(); s.set_access_channels(websocketpp::log::alevel::all); s.clear_access_channels(websocketpp::log::alevel::frame_payload);

s.set_message_handler([](server* s, websocketpp::connection_hdl hdl, server::message_ptr msg) {
    std::string payload = msg->get_payload();
    s->send(hdl, "echo: " + payload, websocketpp::frame::opcode::text);
});

s.listen("0.0.0.0", "9002");
s.start_accept();
s.run();

}

如何处理连接生命周期与错误(on_open / on_close / on_fail)

实际项目中,仅处理消息远远不够。连接建立、异常中断、超时断开等事件必须显式捕获,否则会内存泄漏或状态错乱。

  • on_open 中建议用 s->get_con_from_hdl(hdl) 获取连接对象,保存其 ID 或 IP 地址用于后续管理
  • on_closeon_fail 都需检查 ec(error_code):例如 websocketpp::close::status::going_away 表示正常关闭,而 asio::error::operation_aborted 多见于服务停止时的主动 cancel
  • 不要在 on_fail 中调用 s->close(hdl, ...) —— 此时连接已失效,会触发二次异常
  • 若启用了 ping/pong(set_pong_timeout),超时未响应会自动触发 on_close,无需手动心跳检测

为什么 send() 后客户端收不到消息?

最常被忽略的是:websocketpp 默认启用 permessage-deflate 压缩(即使没协商成功),而某些 JS 客户端(如浏览器原生 WebSocket)不支持该扩展,导致静默丢包。

  • 解决方法:初始化 server 后立即禁用压缩:
    s.clear_access_channels(websocketpp::log::alevel::decompress_failure);
    s.set_permessage_deflate_enabled(false);
  • 另一个原因是异步发送未等待完成:若在 on_message 中连续调用多次 send(),且未检查返回的 future(仅当启用 asio::io_context::strand 时才返回),可能因缓冲区满而丢弃后续消息
  • 调试技巧:启用 websocketpp::log::alevel::frame_header 查看每帧 opcode 和 length,确认是否真的发出了数据

真正麻烦的不是写通 echo,而是连接数增长后如何安全地广播、如何跨线程管理 connection_hdl、如何配合现有 event loop(比如 Qt 或 libuv)。这些地方 websocketpp 不提供银弹,得靠你自己加锁、引用计数或消息队列 —— 它只是个协议栈,不是应用框架。


# js  # go  # 浏览器  # access  # websocket  # 后端  #   # ai  # c++  # 解决方法  # typedef  # 标准库  # 为什么  # qt  # echo  # Error  # 字符串  # Lambda  # 继承  # Length  # Event  # 线程 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比  如何在万网自助建站平台快速创建网站?  Mybatis 中的insertOrUpdate操作  如何在建站主机中优化服务器配置?  网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?  Android中AutoCompleteTextView自动提示  原生JS实现图片轮播切换效果  如何确保FTP站点访问权限与数据传输安全?  Laravel用户密码怎么加密_Laravel Hash门面使用教程  Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】  详解Android图表 MPAndroidChart折线图  Laravel软删除怎么实现_Laravel Eloquent SoftDeletes功能使用教程  Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议  青岛网站建设如何选择本地服务器?  laravel怎么在请求结束后执行任务(Terminable Middleware)_laravel Terminable Middleware请求结束任务执行方法  利用 Google AI 进行 YouTube 视频 SEO 描述优化  EditPlus中的正则表达式实战(5)  如何快速搭建虚拟主机网站?新手必看指南  如何用腾讯建站主机快速创建免费网站?  详解jQuery中基本的动画方法  今日头条微视频如何找选题 今日头条微视频找选题技巧【指南】  java中使用zxing批量生成二维码立牌  Laravel路由怎么定义_Laravel核心路由系统完全入门指南  如何在IIS服务器上快速部署高效网站?  Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧  Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤  ,交易猫的商品怎么发布到网站上去?  VIVO手机上del键无效OnKeyListener不响应的原因及解决方法  浅谈javascript alert和confirm的美化  如何在阿里云高效完成企业建站全流程?  如何在服务器上三步完成建站并提升流量?  Laravel如何实现数据导出到PDF_Laravel使用snappy生成网页快照PDF【方案】  千问怎样用提示词获取健康建议_千问健康类提示词注意事项【指南】  百度浏览器如何管理插件 百度浏览器插件管理方法  Linux系统命令中screen命令详解  香港服务器网站推广:SEO优化与外贸独立站搭建策略  独立制作一个网站多少钱,建立网站需要花多少钱?  深圳网站制作的公司有哪些,dido官方网站?  php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】  如何快速配置高效服务器建站软件?  如何在HTML表单中获取用户输入并用JavaScript动态控制复利计算循环  谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复  Laravel storage目录权限问题_Laravel文件写入权限设置  如何基于云服务器快速搭建个人网站?  Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】  google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】  Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解  香港服务器租用每月最低只需15元?