生产环境优先选uWebSockets或Boost.Beast:前者性能高、API简洁(C++17起稳定),后者与Asio生态无缝衔接;避开libwebsockets的C风格API和已停更的websocketpp。

用什么 C++ WebSocket 库才靠谱
别自己从零写 WebSocket 协议解析——RFC 6455 里帧掩码、握手升级、ping/pong 状态机这些细节容易翻车。生产环境优先选 uWebSockets 或 Boost.Beast。uWebSockets 性能高、API 简洁,但 C++17 起才稳定支持;Boost.Beast 依赖 Boost,编译慢点,但和 asio 生态无缝衔接,适合已有 Boost 基础的项目。
避开 libwebsockets 的 C 风格 API(C++ 里裸指针管理太累),也别用已停止维护的 websocketpp(最新 commit 是 2021 年)。
怎么让多个服务实例共享聊天室状态
WebSocket 连接是长连接,天然绑定在单台服务器上。要实现“用户 A 在机器 1 上发消息,用户 B 在机器 2 上立刻收到”,必须把“发消息”这个动作拆成两步:本地广播 + 跨节点通知。
- 本地内存只存本机连接(比如用
std::unordered_map<connection_id websocket_session_ptr></connection_id>),不存全局用户列表 - 所有“发消息”操作先写入分布式消息总线,比如
Redis Pub/Sub或Kafka;每个服务实例都订阅同一个 channel,收到后只往本机在线连接广播 - 避免用 Redis Key-Value 存“谁在哪个房间”——高并发下
SET/GET竞态多,改用Redis Streams或带原子操作的Redis Hash + HINCRBY管理房间成员数
如何处理连接断开和消息可靠性
WebSocket 没有内置 ACK,TCP 断连时服务端不一定立刻感知(尤其 NAT 后的移动设备)。不能靠 on_close 回调清理房间状态。
立即学习“C++免费学习笔记(深入)”;
- 客户端必须定时发
ping(比如 30s 一次),服务端用ws->setIdleTimeout(45)触发超时回调,主动 close 连接 - 关键消息(如“加入房间”“踢出用户”)走“写 Redis + 发 WebSocket”双写,并加
correlation_id;客户端超时未收则重拉房间状态,而不是等推送 - 别在
on_message里做耗时操作(如查 DB),用asio::post或线程池转出,否则阻塞整个 event loop
部署时最常漏掉的三个配置点
代码跑通不等于线上可用。这三个点没调好,压测时连接数上不去或消息乱序:
- Nginx 反向代理必须显式开启 WebSocket 升级:
proxy_set_header Upgrade $http_upgrade;和proxy_set_header Connection "upgrade";,否则 400 错误里看不到具体原因 - Linux 默认
net.core.somaxconn是 128,ulimit -n通常 1024,C++ 服务启动前得sysctl -w net.core.somaxconn=65535并ulimit -n 65535 -
uWebSockets默认用单线程,别忘了app.run(0, 0)启动多 worker;Boost.Beast则要手动io_context分线程,且strand用错会导致回调串行化
跨机房部署时,别假设所有节点时钟一致——用 NTP 同步,否则基于时间戳的消息去重会失效。


















