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

《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.dtcms.com/a/353544.html

相关文章:

  • 媒体发布平台哪家好?软文营销专业服务商测评推荐
  • 教程:计算中国县级耕地 NDVI 均值并导出 CSV(MODIS)
  • MySQL 基础:DDL、DML、DQL、DCL 四大类 SQL 语句全解析
  • Windows系统Docker中Xinference 集群无法启动的解决方法
  • 深度剖析HTTP和HTTPS
  • LIO-SAM的后端
  • 【stm32简单外设篇】-4×4 薄膜键盘
  • 主流技术栈 NestJS、TypeScript、Node.js版本使用统计
  • 打印机共享修复,打印机无法共享,打印机修复工具下载及安装
  • ChatGPT 上线 “学习模式”:全版本开放,重构 AI 教育逻辑
  • 《电商库存系统超卖事故的技术复盘与数据防护体系重构》
  • 设计模式:桥接模式(Bridge Pattern)
  • C# 使用抽象工厂模式实现花园规划系统的设计与实现
  • electron离线开发核心环境变量npm_config_cache
  • python自学笔记14 NumPy 线性代数
  • 嵌入式linux相机(1)
  • Chrome插件开发【storage】
  • 重学JS-005 --- JavaScript算法与数据结构(五)回顾 DOM 操作
  • 实战Kaggle比赛:狗的品种识别(ImageNet Dogs)
  • SpringBoot整合RabbitMQ:从消息队列基础到高可用架构实战指南
  • 视频孪生技术在人工智能领域的应用价值:从虚实融合到智能决策
  • 人工智能在医疗风险预警中的技术应用综述
  • 《零基础入门AI: 目标检测基础知识》
  • Apache Commons Lang 3
  • 设备电机状态监测:通往预测性维护与效能飞升之路
  • AutoMQ 荣获 AWS Differentiated Partner 顶级认证!
  • 基于改进蜂群优化算法的高频金融波动率预测系统 (源码+论文+部署+安装)
  • ES02-常用API
  • qt c++ QTableWidget
  • Gopher URL协议与SSRF二三事