《websocketpp使用指北》

目录

websocket协议

websocketpp库

安装websocketpp

websocketpp的用法

websocketpp服务器

结果


websocket协议

WebSocket是一种在单个TCP连接上进行全双工通信的应用协议,允许服务端和客户端实时双向数据传输。它通过HTTP/HTTPS的初始握手建立连接,之后转为独立的WebSocket协议通信,适用于需要低延迟和高频交互的场景(如在线游戏、实时聊天)。

websocket协议的出现就是为了解决http协议服务端无法主动向客户端推送信息的问题。

websocketpp库

websocket协议支持多种语言使用,而websocketpp就是C++语言使用的一套与websocket相关的一套API。

安装websocketpp

1.直接使用linux包管理器安装(Centos要使用yum)

sudo apt-get install libwebsocketpp-dev

2.使用源码安装

git clone https://github.com/zaphoyd/websocketpp.git
cd websocketpp
mkdir build && cd build
cmake ..
make
sudo make install

安装好之后检查是否安装成功,查看该目录是否存在,如果存在说明安装成功了;

指令:ls /usr/include/websocketpp

websocketpp的用法

这里我写了个简单的demo来测试websocketpp的使用。

websocketpp服务器

#pragma once#include <iostream>
#include <websocketpp/connection.hpp>
#include <websocketpp/server.hpp>
#include <websocketpp/close.hpp>
#include <websocketpp/config/asio.hpp>
#include <websocketpp/common/functional.hpp>
#include <functional>
#include <sstream>
#include <unordered_set>
#include <vector>
#include <memory>
#include <atomic>
#include <thread>
#include <unistd.h>typedef websocketpp::server<websocketpp::config::asio> websocket_server; // 服务器别名
typedef websocket_server::message_ptr message_ptr;using msg_callback = std::function<void(websocketpp::connection_hdl, websocket_server::message_ptr)>;class Server
{
public:Server() : _count(0){_server.init_asio();                                         // 初始化服务器_server.set_reuse_addr(true);                                // 设置地址重用_server.set_access_channels(websocketpp::log::alevel::none); // 关闭日志// 设置回调函数_server.set_open_handler(bind(&Server::on_open, this, std::placeholders::_1)); // 回调的时候会自动传递一个connection_hdl参数_server.set_close_handler(bind(&Server::on_close, this, std::placeholders::_1));_server.set_message_handler(bind(&Server::on_message, this, std::placeholders::_1, std::placeholders::_2)); // 两个参数(connection_hdl,message_ptr)}// 设置监听端口void set_listen(int port){_server.listen(port); // 0.0.0.0std::cout << "开始监听端口..." << port << std::endl;}// 开始运行服务器void run(){_server.start_accept();_server.run();}void push_message(){std::thread push_thread([this](){while (true){std::stringstream ss;ss << "服务端第" << _count++ << "次推送信息";if(_connections.size()==0){continue;}// 每过5s推送一次信息for (auto &hdl : _connections){std::string content = get_string();std::string push_message = ss.str() + content;                               // 读取缓冲区数据websocket_server::connection_ptr connection = _server.get_con_from_hdl(hdl); // 获取连接指针// 开始推送信息connection->send(push_message);std::cout << "服务端已经推送新信息: " << content << std::endl;sleep(5);}} });push_thread.detach();}private:// 用于测试服务端主动测试的字符串std::string get_string(){std::string str = "acbakjvbaklbvabildhnakfna";// 使用随机数,随机获取区间,截取int start = rand() % str.size();int end = start + rand() % (str.size() - start);return str.substr(start, end);}// 注册连接回调函数void on_open(websocketpp::connection_hdl hdl){std::cout << "有一个新连接到来..." << std::endl; // 提示信息_connections.insert(hdl);}// 注册关闭回调函数void on_close(websocketpp::connection_hdl hdl){std::cout << "有一个连接关闭..." << std::endl;_connections.erase(hdl);}// 注册处理消息回调函数void on_message(websocketpp::connection_hdl hdl, message_ptr msg){std::string message = msg->get_payload(); // 读取消息std::cout << "客户端消息:" << message << std::endl;// 下面是响应处理逻辑std::string echo_response = "服务端收到消息:";echo_response += message;// 将连接句柄转化为连接指针websocket_server::connection_ptr connection = _server.get_con_from_hdl(hdl);// 发送响应connection->send(echo_response);std::cout << "响应:" << echo_response << std::endl;}// 构建链接句柄哈希struct connection_hdl_hash{std::size_t operator()(const websocketpp::connection_hdl &hdl) const{return reinterpret_cast<std::size_t>(hdl.lock().get());}};struct connection_hdl_equal{bool operator()(const websocketpp::connection_hdl &a, const websocketpp::connection_hdl &b) const{return !a.owner_before(b) && !b.owner_before(a);}};std::unordered_set<websocketpp::connection_hdl,connection_hdl_hash,connection_hdl_equal>_connections;websocket_server _server;std::atomic<size_t> _count;// std::unordered_set<websocketpp::connection_hdl, connection_hdl_hash> _connections;
};class ServerBuilder
{
public:std::shared_ptr<Server> build(){return std::make_shared<Server>();}
};

websocketpp客户端

#include <iostream>
#include <websocketpp/connection.hpp>
#include <websocketpp/client.hpp>
#include <websocketpp/close.hpp>
#include <websocketpp/config/asio.hpp>
#include <websocketpp/common/functional.hpp>
#include <functional>
#include <unordered_set>
#include <vector>using namespace std;using websocket_client = websocketpp::client<websocketpp::config::asio>;// 客户端对象
websocket_client client;// 连接句柄
websocket_client::connection_ptr con_ptr;void on_message(websocketpp::connection_hdl, websocket_client::message_ptr msg)
{cout << "Received message: " << msg->get_payload() << endl;
}void on_open(websocketpp::connection_hdl hdl)
{if (hdl.lock() != nullptr) // lock方法是获取连接句柄的智能指针{std::cout << "连接成功!" << std::endl;con_ptr = client.get_con_from_hdl(hdl);std::thread echo_thread([]() {if (con_ptr != nullptr){while (true){std::cout << "请输入要发送的信息>";std::string message;std::cin >> message;con_ptr->send(message);std::cout << "消息发送成功!" << std::endl;}}});echo_thread.detach();}elsestd::cerr << "连接失败!" << std::endl;
}// 连接关闭时调用的,只要调用了就是连接关闭了
void on_close(websocketpp::connection_hdl hdl)
{if (hdl.lock() != nullptr){std::cout << "连接关闭!" << std::endl;}
}int main()
{client.init_asio();                                         // 初始化client.set_access_channels(websocketpp::log::alevel::none); // 关闭日志client.set_open_handler(&on_open);client.set_message_handler(&on_message);client.set_close_handler(&on_close);websocketpp::lib::error_code ec;auto con = client.get_connection("ws://0.0.0.0:8005", ec);if (ec){std::cout << "连接端口8005失败: " << ec.message() << std::endl;return 1;}client.connect(con);// 不再在 main 中创建输入线程,输入线程在 on_open 回调中启动// 运行客户端client.run();return 0;
}

makefile文件


all:server clientserver:server.cc g++ -o server server.cc -std=c++11 -lboost_system -lssl -lcrypto
client:client.ccg++ -o $@ $^ -std=c++11 -lboost_system -lssl -lcrypto.PHONY:clean
clean:rm -rf server client

结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/920283.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/920283.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设备电机状态监测:通往预测性维护与效能飞升之路

在如今竞争白热化的工业领域&#xff0c;企业对设备的高效稳定运转那可是相当看重。预测性维护就像个 “秘密武器”&#xff0c;在降低运营成本、提升设备可用性方面&#xff0c;作用大得很。它好比给设备请了个 “神机妙算” 的预言家&#xff0c;能提前察觉潜在故障&#xff…

Python 网络编程(相关模块)

相关模块 表2-4 列出了其他一些与网络和套接字编程有关的Python 模块。当开发低级套接字 程序时&#xff0c;经常配合使用select 模块和socket 模块。select 模块提供了select()函数&#xff0c;该函数 管理套接字对象集合。它所做的最有用的一个事情就是接收一套套接字&#x…

什么是可持续的联系?通过可持续联系提高用户粘性与复购率

什么是可持续的联系&#xff1f; 在人与人、组织或社区之间&#xff0c;可持续的联系是通过持续互动与合作&#xff0c;构建长期、稳定且互利的关系网。它以信任、沟通和价值认同为核心&#xff0c;帮助实现资源共享与协同成长&#xff0c;并提升各方在复杂环境中的适应能力。…

springboot 分片上传文件 - postgres(BLOB存储)

springboot 分片上传文件 - postgres&#xff08;BLOB存储&#xff09; 方案一&#xff08;推荐&#xff09; ​ 接收完整文件&#xff0c;后端自动分片并存储&#xff08;多线程 大文件&#xff09;/*** 接收完整文件&#xff0c;后端自动分片并存储&#xff08;多线程 大文件…

AI应用--接口测试篇

1. 接口测试过程中的痛点接口的内容都是在yapi上&#xff0c;接口的内容都是以表格的形式呈现。在接口测试过程中&#xff0c;需要将表格形式的入参&#xff0c;手动敲成JSON格式&#xff0c;并且需要跟进字段类型&#xff0c;编辑字段值的形式。过程较为麻烦。使用postman进行…

Boris FX Samplitude Suite 2025.0.0 音频录制/编辑和母带处理

描述 Samplitude是一款专业的DAW&#xff0c;用于录音、编辑、混音和母带制作。通过基于对象的编辑和多轨录音&#xff0c;可以更快地进行创作。 原生杜比全景声 &#xff08;Dolby Atmos&#xff09; 支持 体验音频制作的新维度。由于集成了杜比全景声 &#xff08;Dolby Atm…

龙虎榜——20250827

上证指数今天放量下跌&#xff0c;收大阴线跌破5天均线&#xff0c;形成强势顶分型&#xff0c;日线转回调的概率很大。目前均线依然是多头排列&#xff0c;但是离60天均线较远&#xff0c;有回归均线的需求。深证指数今天放量收长上影的大阴线&#xff0c;日内高点12665.36&am…

项目智能家居---OrangePi全志H616

1 需求及项目准备 语音接入控制各类家电,如客厅灯、卧室灯、风扇。 Socket编程,实现Sockect发送指令远程控制各类家电。 烟雾警报监测, 实时检查是否存在煤气泄漏或者火灾警情,当存在警情时及时触发蜂鸣器报警及语音播报。 控制人脸识别打开房门功能,并语音播报识别成功或…

项目概要设计说明文档

一、 引言 &#xff08;一&#xff09; 编写目的 &#xff08;二&#xff09; 范围 &#xff08;三&#xff09; 文档约定 &#xff08;四&#xff09; 术语 二、 项目概要 &#xff08;一&#xff09; 建设背景 &#xff08;二&#xff09; 建设目标 &#xff08;三&a…

解决mac brew4.0安装速度慢的问题

Homebrew 4.0 版本的重大变化自 Homebrew 4.0 版本起&#xff0c;官方弃用了传统的 homebrew-core Git 仓库模式&#xff0c;改为通过 API&#xff08;formulae.brew.sh&#xff09; 获取软件包元数据。因此&#xff0c;手动替换 homebrew-core 仓库的目录可能不再存在。目录结…

AI需求优先级:数据价值密度×算法成熟度

3.3 需求优先级模型:ROI(数据价值密度算法成熟度) 核心公式: AI需求ROI = 数据价值密度 算法成熟度 总优先级 = ROI 伦理合规系数 (系数范围:合规=1.0,高风险=0~0.5) 一、数据价值密度:从数据垃圾到石油精炼 量化评估模型(融合3.1节数据可行性) 维度 评估指标…

手写MyBatis第37弹: 深入MyBatis MapperProxy:揭秘SQL命令类型与动态方法调用的完美适配

&#x1f942;(❁◡❁)您的点赞&#x1f44d;➕评论&#x1f4dd;➕收藏⭐是作者创作的最大动力&#x1f91e; &#x1f496;&#x1f4d5;&#x1f389;&#x1f525; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd;欢迎留言讨论 &#x1f525;&#x1f525;&…

GD32VW553-IOT 测评和vscode开发环境搭建

GD32VW553-IOT 测评和vscode开发环境搭建 1. 背景介绍 iCEasy商城的产品, Firefly Workshop 萤火工厂的样片, 是一款基于GD32VW553 MCU的开源硬件, 这款MCU内置了32bit的RISC-V内核, 支持双模无线WIFI-6和BLE-5.2, 最高主频可达160Mhz. 本人曾在公司参与开发了一款基于RISC-V内…

斯塔克工业技术日志:用基础模型打造 “战甲级” 结构化 AI 功能

引子 在斯塔克工业的地下研发实验室里&#xff0c;弧光反应堆的蓝光映照着布满代码的显示屏&#xff0c;工程师詹姆斯・“罗迪”・罗德斯正对着一堆 AI 生成的杂乱食谱皱眉。 上周他刚搞定基础模型&#xff08;Foundation Models&#xff09;的文本生成&#xff0c;让 AI 能像…

如何解决pip安装报错ModuleNotFoundError: No module named ‘click’问题

【Python系列Bug修复PyCharm控制台pip install报错】如何解决pip安装报错ModuleNotFoundError: No module named ‘click’问题 摘要 在日常Python开发中&#xff0c;pip install 报错 ModuleNotFoundError: No module named click 是一个非常常见的问题&#xff0c;尤其是在…

PLC_博图系列☞基本指令”S_PULSE:分配脉冲定时器参数并启动“

PLC_博图系列☞基本指令”S_PULSE&#xff1a;分配脉冲定时器参数并启动“ 文章目录PLC_博图系列☞基本指令”S_PULSE&#xff1a;分配脉冲定时器参数并启动“背景介绍S_PULSE&#xff1a; 分配脉冲定时器参数并启动说明参数脉冲时序图示例关键字&#xff1a; PLC、 西门子、 …

【大模型】Qwen2.5-VL-3B模型量化以及运行测试,保留多模态能力(实践版)

目录 ■获取原始模型 ■构建llama.cpp ■转换模型到GGUF ▲视觉模块转换 ▲llm模块转换 ▲llm模块量化 ▲推理测试 ■报错处理 以下是几种多模态模型量化方案的简要对比: 特性 llama.cpp GGUF 量化

C语言 | 高级C语言面试题

侧重于内存管理、指针、编译器行为、底层原理和编程实践。 C语言面试 一、核心概念与深度指针题 1. `const` 关键字的深度理解 2. volatile 关键字的作用 3. 复杂声明解析 二、内存管理 4. `malloc(0)` 的行为 5. 结构体内存对齐与大小计算 三、高级技巧与底层原理 6. setjmp()…

【deepseek问答记录】:chatGPT的参数数量和上下文长度有关系吗?

这是一个非常好的问题&#xff0c;它触及了大型语言模型设计的核心。 简单来说&#xff1a;参数数量和上下文长度在技术上是两个独立的概念&#xff0c;但在模型的设计、训练和实际应用中&#xff0c;它们存在着深刻且重要的联系。 我们可以从以下几个层面来理解它们的关系&…

5GNR CSI反馈 TypeI码本

5GNR CSI反馈 TypeI码本 前言 最近孬孬在学习5gnr中的CSI反馈内容&#xff0c;对于目前的5GNR主要是基于码本的隐式反馈机制&#xff0c;在NR中主要是分为 TypeI 和 TypeII&#xff0c;对于TypeI是用于常规精度的&#xff0c;对于TypeII更为复杂&#xff0c;更多的适用于多用户…