自学内容网 自学内容网

Websocket++ 框架

概述

基于 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;
}


原文地址:https://blog.csdn.net/gma999/article/details/144013651

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!