当前位置: 首页 > news >正文

用 C++ 快速搭建 WebSocket 服务及踩坑记录

用 C++ 快速搭建 WebSocket 服务及踩坑记录

做实时数据交互(比如设备监控、即时通知)时,HTTP 轮询总绕不开两个问题:延迟高、浪费服务器资源。而 WebSocket 的长连接特性,能让前后端主动互发数据,刚好解决这些痛点。

如果你的项目后端是 C++ 技术栈,用 WebSocketpp 库搭 WebSocket 服务很合适 —— 轻量、不用切换语言,还能直接对接现有业务逻辑。这篇就从环境搭建到前后端联调,一步步讲清楚怎么实现,顺便避避常见的坑。

一、先搞懂:为什么选 WebSocket 而非 HTTP 轮询?

HTTP 轮询是 “客户端问、服务器答”,哪怕没新数据,也要频繁发请求,不仅延迟能到几秒,还会占用额外带宽。而 WebSocket 一旦握手成功,就是双向长连接:

  • 服务器能主动推数据(比如设备状态更新后,立马传给前端);

  • 没有多余 HTTP 头开销,延迟能压到 100ms 内;

  • 不用频繁建立连接,省服务器资源。

二、环境搭建:Ubuntu 装 WebSocketpp 和 Boost

WebSocketpp 是头文件库,但依赖 Boost(主要用 asio 网络模块),直接用 apt 安装最省心:

# 装 Boost 核心库(asio 依赖)
sudo apt-get install libboost-dev libboost-system-dev
# 装 WebSocketpp
sudo apt-get install libwebsocketpp-dev

装完验证下:执行 ls /usr/include/websocketpp/,能看到 connection.hppendpoint_base.hpp 等文件,就说明装对了。

三、服务器端代码:C++ 实现核心逻辑

WebSocketpp 核心是 “事件驱动”,重点写连接、消息、断开的回调函数,再初始化启动服务器即可。

1. 定义基础类型

先指定配置(用不加密的 asio_no_tls),简化后续代码:

#include <iostream>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>// 服务器类型
typedef websocketpp::server<websocketpp::config::asio> server_t;
// 消息指针类型
typedef server_t::message_ptr message_ptr;

2. 写回调函数

(1)连接建立:onOpen

连接成功时打日志,方便调试:

void onOpen(websocketpp::connection_hdl hdl) {std::cout << "✅ 新连接建立" << std::endl;
}
(2)连接断开:onClose

断开时清理日志:

void onClose(websocketpp::connection_hdl hdl) {std::cout << "❌ 连接断开" << std::endl;
}
(3)处理消息:onMessage(核心)

收到前端消息后,加后缀 “-Hello!” 回传(类似回声服务,实际项目可替换成业务逻辑):

void onMessage(server_t *server, websocketpp::connection_hdl hdl, message_ptr msg) {// 拿消息内容std::string body = msg->get_payload();std::cout << "📥 收到消息:" << body << std::endl;// 回消息auto conn = server->get_con_from_hdl(hdl);conn->send(body + "-Hello!", websocketpp::frame::opcode::value::text);std::cout << "📤 回传消息:" << body << "-Hello!" << std::endl;
}

3. 初始化并启动服务器(修复格式版)

按步骤初始化,绑定回调、设端口、启动服务,代码缩进和符号均为标准格式:

int main() {// 实例化服务器server_t server;// 关闭日志(调试时可改 websocketpp::log::alevel::all 打开)server.set_access_channels(websocketpp::log::alevel::none);// 初始化 asioserver.init_asio();// 绑定回调server.set_open_handler(onOpen);server.set_close_handler(onClose);auto msg_handler = std::bind(onMessage, &server, std::placeholders::_1, std::placeholders::_2);server.set_message_handler(msg_handler);// 启用地址重用(避免端口占用报错)server.set_reuse_addr(true);// 设端口、启动监听server.listen(8080);std::cout << "🚀 服务器启动,监听 ws://localhost:8080" << std::endl;// 接收连接、启动服务server.start_accept();server.run();return 0;
}

四、客户端代码:HTML+JS 快速测试

浏览器原生支持 WebSocket API,写个简单页面就能测:

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>WebSocket 测试</title><style>body { padding: 20px; }#message { width: 300px; padding: 8px; }#submit { padding: 8px 16px; background: #4285f4; color: white; border: none; }</style>
</head>
<body><input type="text" id="message" placeholder="输入消息"><button id="submit">发送</button><script>// 连服务器(替换成你的服务器 IP)const websocket = new WebSocket("ws://192.168.195.128:8080");// 连接成功websocket.onopen = () => console.log("✅ 客户端连成功");// 收消息websocket.onmessage = (e) => console.log("📥 收服务端消息:", e.data);// 出错websocket.onerror = () => console.error("❌ 连接异常");// 断开websocket.onclose = () => console.log("❌ 连接关闭");// 点击发送const input = document.querySelector("#message");const btn = document.querySelector("#submit");btn.onclick = () => {const msg = input.value.trim();if (msg) {websocket.send(msg);console.log("📤 发消息:", msg);input.value = "";}};</script>
</body>
</html>

五、联调测试:一步到位跑通

1. 编译服务器代码

WebSocketpp 依赖 Boost 和线程库,编译时要加参数:

# 假设代码存为 ws_server.cpp
g++ -o ws_server ws_server.cpp -lboost_system -pthread

2. 启动服务器

./ws_server

看到 “🚀 服务器启动,监听 ws://localhost:8080”,就是成功了。

3. 测试客户端

  1. 用浏览器打开 HTML 文件,按 F12 开控制台;

  2. 输入消息(比如 “Hi”),点 “发送”;

  3. 看两端日志:

  • 服务器:✅ 新连接建立📥 收到消息:Hi📤 回传消息:Hi-Hello!

  • 客户端:✅ 客户端连成功📤 发消息:Hi📥 收服务端消息:Hi-Hello!

这样就说明联调通了!

六、踩坑记录:避坑指南

  1. 编译报错 “undefined reference”:没加 -lboost_system-pthread,补全参数即可;

  2. 客户端连不上:检查服务器 IP 是不是写对(比如虚拟机里的服务器,不能用 localhost);

  3. 端口占用:用 netstat -tuln | grep 8080 查占用进程,kill 后重启;

  4. 日志太乱:默认日志多,用 set_access_channels(websocketpp::log::alevel::none) 关掉。

总结

用 WebSocketpp 搭 C++ WebSocket 服务,不用自己解析协议,核心就是写回调和初始化。适合 C++ 技术栈的实时场景,轻量又好整合现有业务。按上面的步骤走,基本能避开大部分坑,快速跑通功能。

http://www.dtcms.com/a/445506.html

相关文章:

  • 清华大学AI领导力AI时代领导力AI变革领导力培训师培训讲师专家唐兴通讲授数字化转型人工智能组织创新实践领导力国央企国有企业金融运营商制造业
  • pink老师html5+css3day04
  • 网站系统报价方案模板下载维普网论文收录查询
  • 【C++ STL栈和队列下】deque(双端队列) 优先级队列的模拟实现与仿函数的介绍
  • Linux-> TCP 编程1
  • [人工智能-综述-18]:AI重构千行百业的技术架构
  • gps定位网站建设梧州自助建站seo
  • [论文阅读] AI+教学 | 编程入门课的AI助手革命?ChatGPT的4大核心影响全解析
  • 设计模式学习(五)装饰者模式、桥接模式、外观模式
  • 邵阳网站建设上科互联百度网站如何建设
  • 使用Yocto构建qemu上的Linux系统
  • Scade One 图形建模 - 选择算符模型
  • 【Java SE 异常】原理、处理与实践详解​
  • CPP学习之哈希表
  • Java “并发工具类”面试清单(含超通俗生活案例与深度理解)
  • 2025 AI伦理治理破局:从制度设计到实践落地的探索
  • 力扣1984. 学生分数的最小差值
  • Android studio -kt构建一个app
  • 4.数据类型
  • Spring Boot SSE 流式输出,智能体的实时响应
  • Linux系统性能监控—sar命令
  • PostgreSQL备份不是复制文件?物理vs逻辑咋选?误删还能精准恢复到1分钟前?
  • 网站开发主管招聘wordpress 手机悬浮
  • 描述逻辑对人工智能自然语言处理中深层语义分析的影响与启示
  • 首屏加载耗时从5秒优化到1秒内:弱网与低端安卓机下的前端优化秘笈
  • 【新版】Elasticsearch 8.15.2 完整安装流程(Linux国内镜像提速版)
  • LeetCode 分类刷题:74. 搜索二维矩阵
  • 网站建设项目职责memcache安装wordpress
  • MySQL查看数据表锁定情况
  • sq网站推广用jsp做的网站源代码下载