Websocket++ 框架

embedded/2024/11/26 13:34:51/

概述

基于 C++ 标准的 WebSocket 协议实现,适合使用 C++11 或更高版本开发的项目,支持构建 WebSocket 客户端和服务器,功能灵活,设计模块化,非常适合高性能的网络通信场景

主要特点

  • 支持 WebSocket 客户端和服务器
  • 默认支持同步和异步 I/O;可以与 Boost.Asio 或其他异步 I/O 库集成,适应多种开发需求
  • 支持加密的 WebSocket 通信,需要链接 OpenSSL 等库
  • 通过 C++11 的特性优化性能(如智能指针、线程等);提供事件回调机制,减少资源占用
  • 支持自定义协议、扩展和日志记录;可以根据项目需要启用或禁用功能

原理理解

Websocket本质是TCP协议。客户端先和服务器先通过HTTP请求,然后在这个请求的基础上完成握手过程同时升级协议

报文格式

  • FIN:表示该消息是否结束
  • Opcode:指明帧类型(如文本帧、二进制帧、关闭帧等)
  • Mask:表示是否使用掩码(客户端消息必须使用掩码)
  • Payload length:表示数据长度
  • Payload data:实际的数据

全双工通信

一旦握手完成,客户端和服务器之间的连接是全双工的,允许任意一方主动发送或接收消息,而无需等待请求/响应模型

核心实现理解

网络通信

Websocket++是建立在Boost::Asio的网络通信机制上的,其是支持异步通信以及可以通过TCP连接实现底层的字节流传输

事件驱动模型

WebSocket++ 使用事件驱动模型来处理连接的生命周期

  • on_open:处理连接建立事件
  • on_message:处理消息接收事件
  • on_close:处理连接关闭事件
  • on_fail:处理连接失败事件

双向通信的实现

  • 收到消息时,通过事件处理函数将消息传递给用户定义的回调函数
  • 发送消息时,将数据封装为帧并通过 TCP 发送

常用接口

Server类

Server类的主要功能就是快速搭建一个Websocket服务器,其内部封装了Websocket协议的所有服务器端功能,提供了处理连接、接收消息、发送消息等功能

init_asio()

初始化 ASIO 库。WebSocket++ 使用 ASIO 作为底层网络通信库,因此需要调用此函数来初始化 ASIO

server.init_asio();

set_reuse_addr()

启用地址复用,在服务器端快速启动或重启 WebSocket 服务

server.set_reuse_addr(true);

set_open_handler()

设置 WebSocket 连接打开时的回调函数。当一个客户端连接到服务器时,调用该回调

server.set_open_handler([](websocketpp::connection_hdl hdl) {std::cout << "Client connected!" << std::endl;
});

set_close_handler()

设置 WebSocket 连接关闭时的回调函数。连接关闭时将调用该回调

server.set_close_handler([](websocketpp::connection_hdl hdl) {std::cout << "Client disconnected!" << std::endl;
});

set_message_handler()

设置接收到消息时的回调函数。客户端发送消息时,会触发该回调函数

server.set_message_handler([](websocketpp::connection_hdl hdl, server::message_ptr msg) {std::cout << "Received message: " << msg->get_payload() << std::endl;
});

listen()

启动服务器并监听指定的端口

server.listen(9002);  // 在端口 9002 上监听

run()

启动事件循环,等待和处理客户端连接和消息

server.run();

Client类

用于 WebSocket 客户端。它也提供了类似于服务器端的功能,包括连接管理、消息处理等

init_asio()

client.init_asio();

set_open_handler()

设置连接建立时的回调函数

client.set_open_handler([](websocketpp::connection_hdl hdl) {std::cout << "Connection established!" << std::endl;
});

set_close_handler()

设置连接关闭时的回调函数

client.set_close_handler([](websocketpp::connection_hdl hdl) {std::cout << "Connection closed!" << std::endl;
});

set_message_handler()

设置接收到消息时的回调函数

client.set_message_handler([](websocketpp::connection_hdl hdl, client::message_ptr msg) {std::cout << "Received message: " << msg->get_payload() << std::endl;
});

connect()

建立 WebSocket 连接

client.connect(endpoint);

run()

启动事件循环,等待并处理消息

client.run();

websocketpp::connection_hdl

websocketpp::connection_hdl是Websocket++中的一个句柄,其表示一个Websocket连接的唯一标识符;其可以传递给服务器和客户端的处理函数,用于标识连接,从而帮助我们执行特定连接的操作

message类

封装了 WebSocket 消息的数据。它包含了消息的有效负载和其他相关信息

get_payload():获取消息的有效负载部分,即客户端或服务器接收到的消息内容

std::string payload = msg->get_payload();

set_payload():设置消息的有效负载部分

msg->set_payload("Hello, WebSocket!");

使用

服务器搭建

#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>//1. 定义Server类型
typedef websocketpp::server<websocketpp::config::asio> server_t;void onOpen(websocketpp::connection_hdl hdl) {std::cout << "websocket长连接建立成功!\n";
}
void onClose(websocketpp::connection_hdl hdl) {std::cout << "websocket长连接断开!\n";   
}
void onMessage(server_t *server, websocketpp::connection_hdl hdl, server_t::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);
}int main()
{//2. 实例化服务器对象server_t server;//3. 初始化日志输出server.set_access_channels(websocketpp::log::alevel::none);//4. 初始化asio框架server.init_asio();// 5. 设置消息处理、连接握手成功、连接关闭回调函数server.set_open_handler(onOpen);server.set_close_handler(onClose);auto msg_hadler = std::bind(onMessage, &server, std::placeholders::_1, std::placeholders::_2);server.set_message_handler(msg_hadler);// 6. 设置监听端口server.set_reuse_addr(true);// 7. 开始监听server.listen(8888);server.start_accept();// 8. 启动服务器server.run();return 0;
}


http://www.ppmy.cn/embedded/140632.html

相关文章

lanqiaoOJ 3745:餐厅排队 ← 数组模拟队列

【题目来源】https://www.lanqiao.cn/problems/3745/learning/【题目描述】 在蓝桥学院的新餐厅&#xff0c;学生们在取餐窗囗形成了一条长队。小蓝&#xff0c;餐厅的经理&#xff0c;希望能够实时了解队伍最前面和最后面的学生编号。你需要执行以下三种操作&#xff1a; 1.学…

Debian/Ubuntu 、Fedora 、Arch Linux, 在Linux上,对文本文件进行多线程压缩 xz、pxz、zstd、7z、lrzip

Debian/Ubuntu 、Fedora 、Arch Linux&#xff0c; 在Linux上&#xff0c;对文本文件进行多线程压缩 xz、pxz、zstd、7z、lrzip 前言对比多线程压缩1. 使用 pxz安装 pxz使用 pxz 2. 使用 xz 的 -T 选项使用 xz -T 3. 其他压缩命令1. 使用 gzip2. 使用 bzip23. 使用 xz4. 使用 7…

sql server 主从job对比差异

---查看job的基本信息 select a.job_id,a.name, a.date_created ,a.date_modified ,case when a.enabled1 then N是when a.enabled0 then N否 end as enabled ,a.description, b.step_id,b.step_name,b.subsystem,b.command,b.database_name,b.last_run_datefrom msdb.dbo.sy…

泷羽sec--轻松了解burp的配置使用及各个模块的作用

声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&#…

docker镜像、容器、仓库介绍

docker docker介绍docker镜像命令docker容器命令docker仓库 docker介绍 官网 Docker 是一种开源的容器化平台&#xff0c;用于开发、部署和运行应用。它通过将应用程序及其依赖项打包到称为“容器”的单一包中&#xff0c;使得应用能够在任何环境下运行&#xff0c;不受底层系…

人工智能之数学基础:向量的基本知识

本文重点 向量的基本性质是线性代数和向量空间理论的核心,它们为向量运算提供了坚实的基础,并在物理、工程、计算机图形学等领域有着广泛的应用。本文对向量的一些基本知识进行介绍,帮助大家快速理解向量。 向量的定义与表示 向量是一个既有大小又有方向的量,通常用带箭…

php 导出excel 一个单元格 多张图片

public function dumpData(){error_reporting(0); // 禁止错误信息输出ini_set(display_errors, 0); // 不显示错误$limit $this->request->post(limit, 20, intval);$offset $this->request->post(offset, 0, intval);$page floor($offset / $limit) 1 ;$wh…

web开发中浏览器的重排与重绘

重排&#xff08;Reflow&#xff09; 和 重绘&#xff08;Repaint&#xff09; 是浏览器在渲染网页时涉及的两个重要过程&#xff0c;它们直接影响网页性能。理解它们的区别和优化方法对于前端开发至关重要。 1. 重排&#xff08;Reflow&#xff09; 定义 重排是指当网页布局…