HTTP实现心跳模块

HTTP实现心跳模块

使用轻量级的c++HTTP库cpp-httplib重现实现HTTP心跳模块

头文件HttplibHeartbeat.h

#ifndef HTTPLIB_HEARTBEAT_H
#define HTTPLIB_HEARTBEAT_H#include <string>
#include <thread>
#include <atomic>
#include <chrono>
#include <functional>
#include <memory>
#include "httplib.h"
#include "json.hpp"using json = nlohmann::json;class HttplibHeartbeat {
public:using ResponseCallback = std::function<void(const std::string& response, bool success)>;/*** @brief 构造函数* @param host 服务器主机名或IP* @param port 服务器端口* @param endpoint 心跳端点路径* @param interval 心跳间隔(秒)*/HttplibHeartbeat(const std::string& host, int port, const std::string& endpoint, unsigned int interval);/** * @param heartbeat_data 心跳数据(将转换为JSON)*/HttplibHeartbeat(const std::string& host, int port, const std::string& endpoint, unsigned int interval,const std::map<std::string, std::string>& heartbeat_data);~HttplibHeartbeat();void start(ResponseCallback callback);void stop();void setInterval(unsigned int interval);bool isRunning() const;void updateHeartbeatData(const std::map<std::string, std::string>& new_data);private:void heartbeatLoop();json createHeartbeatJson() const;std::string m_host;int m_port;std::string m_endpoint;unsigned int m_interval;std::atomic<bool> m_running;std::thread m_thread;ResponseCallback m_callback;std::unique_ptr<httplib::Client> m_client;std::map<std::string, std::string> m_heartbeat_data;
};#endif // HTTPLIB_HEARTBEAT_H

cpp源文件 HttplibHeartbeat.cpp

#include "HttplibHeartbeat.h"
#include <iostream>HttplibHeartbeat::HttplibHeartbeat(const std::string& host, int port, const std::string& endpoint, unsigned int interval): m_host(host), m_port(port), m_endpoint(endpoint), m_interval(interval), m_running(false) {m_client = std::make_unique<httplib::Client>(host, port);// 设置超时时间m_client->set_connection_timeout(3); // 3秒连接超时m_client->set_read_timeout(5);       // 5秒读取超时
}HttplibHeartbeat::HttplibHeartbeat(const std::string& host, int port, const std::string& endpoint, unsigned int interval,const std::map<std::string, std::string>& heartbeat_data): m_host(host), m_port(port), m_endpoint(endpoint), m_interval(interval), m_running(false),m_heartbeat_data(heartbeat_data) {m_client = std::make_unique<httplib::Client>(host, port);m_client->set_connection_timeout(3);m_client->set_read_timeout(5);
}HttplibHeartbeat::~HttplibHeartbeat() {stop();
}void HttplibHeartbeat::start(ResponseCallback callback) {if (m_running) {return;}m_callback = callback;m_running = true;m_thread = std::thread(&HttplibHeartbeat::heartbeatLoop, this);
}void HttplibHeartbeat::stop() {if (!m_running) {return;}m_running = false;if (m_thread.joinable()) {m_thread.join();}
}void HttplibHeartbeat::setInterval(unsigned int interval) {m_interval = interval;
}bool HttplibHeartbeat::isRunning() const {return m_running;
}void HttplibHeartbeat::updateHeartbeatData(const std::map<std::string, std::string>& new_data) {m_heartbeat_data = new_data;
}void HttplibHeartbeat::heartbeatLoop() {while (m_running) {std::string response;bool success = false;if (auto res = m_client->Get(m_endpoint.c_str())) {if (res->status == 200) {response = res->body;success = true;} else {response = "HTTP status: " + std::to_string(res->status);}} else {response = "Error: " + httplib::to_string(res.error());}if (m_callback) {m_callback(response, success);}// 等待下一次心跳for (unsigned int i = 0; i < m_interval && m_running; ++i) {std::this_thread::sleep_for(std::chrono::seconds(1));}}
}
/*
void HttplibHeartbeat::heartbeatLoop() {while (m_running) {json response_json;bool success = false;// 创建心跳JSON数据json request_json = createHeartbeatJson();std::string request_body = request_json.dump();// 设置JSON内容类型头httplib::Headers headers = {{"Content-Type", "application/json"}};if (auto res = m_client->Post(m_endpoint.c_str(), headers, request_body, "application/json")) {if (res->status == 200) {try {response_json = json::parse(res->body);success = true;} catch (const json::parse_error& e) {response_json = {{"error", "Failed to parse server response"},{"details", e.what()},{"raw_response", res->body}};}} else {response_json = {{"error", "HTTP request failed"},{"status", res->status},{"body", res->body}};}} else {response_json = {{"error", "Network error"},{"details", httplib::to_string(res.error())}};}if (m_callback) {m_callback(response_json, success);}// 等待下一次心跳for (unsigned int i = 0; i < m_interval && m_running; ++i) {std::this_thread::sleep_for(std::chrono::seconds(1));}}
}
*/
json HttplibHeartbeat::createHeartbeatJson() const {json j;j["type"] = "heartbeat";j["timestamp"] = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();// 添加自定义心跳数据for (const auto& [key, value] : m_heartbeat_data) {j[key] = value;}return j;
}

使用实例

#include "HttplibHeartbeat.h"
#include <iostream>int main() {// 创建心跳对象,连接localhost:8080,每5秒发送一次心跳HttplibHeartbeat heartbeat("localhost", 8080, "/api/heartbeat", 5);// 定义回调函数auto callback = [](const std::string& response, bool success) {if (success) {std::cout << "[Heartbeat] Success: " << response << std::endl;} else {std::cerr << "[Heartbeat] Failed: " << response << std::endl;}};/*  // 准备心跳数据std::map<std::string, std::string> heartbeat_data = {{"device_id", "12345"},{"version", "1.0.0"},{"status", "active"}};// 创建JSON心跳对象HttplibHeartbeat heartbeat("localhost", 8080, "/api/heartbeat", 10, heartbeat_data);// 定义回调函数auto callback = [](const json& response, bool success) {if (success) {std::cout << "[Heartbeat] Success. Server response:" << std::endl;std::cout << response.dump(4) << std::endl; // 漂亮打印JSON// 可以解析特定字段if (response.contains("next_check_interval")) {std::cout << "Next check in: " << response["next_check_interval"] << "s" << std::endl;}} else {std::cerr << "[Heartbeat] Failed. Error response:" << std::endl;std::cerr << response.dump(4) << std::endl;}};*/// 启动心跳heartbeat.start(callback);std::cout << "Heartbeat started. Press Enter to stop..." << std::endl;std::cin.get();// 停止心跳heartbeat.stop();return 0;
}

编译说明

  1. 下载 cpp-httplib 头文件
  2. httplib.h 放在项目目录中
  3. 编译命令示例:g++ -std=c++11 HttplibHeartbeat.cpp main.cpp -lpthread -o heartbeat

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

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

相关文章

openharmony—release—4.1开发环境搭建(踩坑记录)

环境开发需要分别在window以及ubuntu下进行相应设置 一、window 1.安装DevEco Device Tool OpenAtom OpenHarmony 二、ubuntu 1.将Ubuntu Shell环境修改为bash ls -l /bin/sh 2.打开终端工具&#xff0c;执行如下命令&#xff0c;输入密码&#xff0c;然后选择No&#xff0…

Go学习系列文章声明

本次学习是基于B站的视频&#xff0c;【Udemy高分热门付费课程】Golang&#xff1a;完整开发者指南&#xff08;基础知识和高级特性&#xff09;中英文字幕_哔哩哔哩_bilibili 本人会尝试输出视频中的内容&#xff0c;如有错误欢迎指出 next page: Go installation process

error: RPC failed; HTTP 408 curl 22 The requested URL returned error: 408

在git push时报错&#xff1a;error: RPC failed; HTTP 408 curl 22 The requested URL returned error: 408 原因&#xff1a;可能是推送的文件太大&#xff0c;要么是缓存不够&#xff0c;要么是网络不行。 解决方法&#xff1a; 将本地 http.postBuffer 数值调整到500MB&…

Android.bp中添加条件判断编译方式

背景&#xff1a; 马哥学员朋友以前在vip群里&#xff0c;有问道如何在Android.bp中添加条件判断&#xff0c;在工作中经常需要一套代码兼容发货目标版本&#xff0c;即代码都是公共的一套&#xff0c;但是需要用这一套代码集成到各个产品设备上 但是这个产品设备可能面临比…

swift ui基础

一个朴实无华的目录 今日学习内容&#xff1a;1.三种布局&#xff08;可以相互包裹&#xff09;1.1 vstack&#xff08;竖直&#xff09;&#xff1a;先写的在上面1.1 hstack&#xff08;水平&#xff09;&#xff1a;先写的在左边1.1 zstack&#xff08;前后&#xff09;&…

第16届蓝桥杯单片机模拟试题Ⅲ

试题 代码 sys.h #ifndef __SYS_H__ #define __SYS_H__#include <STC15F2K60S2.H> //sys.c extern unsigned char UI; //界面标志(0湿度界面、1参数界面、2时间界面) extern unsigned char time; //时间间隔(1s~10S) extern bit ssflag; //启动/停止标志…

Node.js中URL模块详解

Node.js 中 URL 模块全部 API 详解 1. URL 类 const { URL } require(url);// 1. 创建 URL 对象 const url new URL(https://www.example.com:8080/path?queryvalue#hash);// 2. URL 属性 console.log(协议:, url.protocol); // https: console.log(主机名:, url.hos…

Java接口性能优化面试问题集锦:高频考点与深度解析

1. 如何定位接口性能瓶颈&#xff1f;常用哪些工具&#xff1f; 考察点&#xff1a;性能分析工具的使用与问题定位能力。 核心答案&#xff1a; 工具&#xff1a;Arthas&#xff08;在线诊断&#xff09;、JProfiler&#xff08;内存与CPU分析&#xff09;、VisualVM、Prometh…

WheatA小麦芽:农业气象大数据下载器

今天为大家介绍的软件是WheatA小麦芽&#xff1a;专业纯净的农业气象大数据系统。下面&#xff0c;我们将从软件的主要功能、支持的系统、软件官网等方面对其进行简单的介绍。 主要内容来源于软件官网&#xff1a;WheatA小麦芽的官方网站是http://www.wheata.cn/ &#xff0c;…

Python10天突击--Day 2: 实现观察者模式

以下是 Python 实现观察者模式的完整方案&#xff0c;包含同步/异步支持、类型注解、线程安全等特性&#xff1a; 1. 经典观察者模式实现 from abc import ABC, abstractmethod from typing import List, Anyclass Observer(ABC):"""观察者抽象基类""…

CST1019.基于Spring Boot+Vue智能洗车管理系统

计算机/JAVA毕业设计 【CST1019.基于Spring BootVue智能洗车管理系统】 【项目介绍】 智能洗车管理系统&#xff0c;基于 Spring Boot Vue 实现&#xff0c;功能丰富、界面精美 【业务模块】 系统共有三类用户&#xff0c;分别是&#xff1a;管理员用户、普通用户、工人用户&…

Windows上使用Qt搭建ARM开发环境

在 Windows 上使用 Qt 和 g++-arm-linux-gnueabihf 进行 ARM Linux 交叉编译(例如针对树莓派或嵌入式设备),需要配置 交叉编译工具链 和 Qt for ARM Linux。以下是详细步骤: 1. 安装工具链 方法 1:使用 MSYS2(推荐) MSYS2 提供 mingw-w64 的 ARM Linux 交叉编译工具链…

Python爬虫教程011:scrapy爬取当当网数据开启多条管道下载及下载多页数据

文章目录 3.6.4 开启多条管道下载3.6.5 下载多页数据3.6.6 完整项目下载3.6.4 开启多条管道下载 在pipelines.py中新建管道类(用来下载图书封面图片): # 多条管道开启 # 要在settings.py中开启管道 class DangdangDownloadPipeline:def process_item(self, item, spider):…

Mysql -- 基础

SQL SQL通用语法&#xff1a; SQL分类&#xff1a; DDL: 数据库操作 查询&#xff1a; SHOW DATABASES&#xff1b; 创建&#xff1a; CREATE DATABASE[IF NOT EXISTS] 数据库名 [DEFAULT CHARSET字符集] [COLLATE 排序规则]&#xff1b; 删除&#xff1a; DROP DATABA…

实操(环境变量)Linux

环境变量概念 我们用语言写的文件编好后变成了程序&#xff0c;./ 运行的时候他就会变成一个进程被操作系统调度并运行&#xff0c;运行完毕进程相关资源被释放&#xff0c;因为它是一个bash的子进程&#xff0c;所以它退出之后进入僵尸状态&#xff0c;bash回收他的退出结果&…

torch.cat和torch.stack的区别

torch.cat 和 torch.stack 是 PyTorch 中用于组合张量的两个常用函数&#xff0c;它们的核心区别在于输入张量的维度和输出张量的维度变化。以下是详细对比&#xff1a; 1. torch.cat (Concatenate) 作用&#xff1a;沿现有维度拼接多个张量&#xff0c;不创建新维度 输入要求…

深入解析@Validated注解:Spring 验证机制的核心工具

一、注解出处与核心定位 1. 注解来源 • 所属框架&#xff1a;Validated 是 Spring Framework 提供的注解&#xff08;org.springframework.validation.annotation 包下&#xff09;。 • 核心定位&#xff1a; 作为 Spring 对 JSR-380&#xff08;Bean Validation 2.0&#…

2025年认证杯数学建模竞赛A题完整分析论文(含模型、可运行代码)(共32页)

2025年认证杯数学建模竞赛A题完整分析论文 目录 摘要 一、问题分析 二、问题重述 三、模型假设 四、 模型建立与求解 4.1问题1 4.1.1问题1解析 4.1.2问题1模型建立 4.1.3问题1样例代码&#xff08;仅供参考&#xff09; 4.1.4问题1求解结果分析&#xff08…

Google A2A协议,是为了战略性占领标准?

一、导读 2025 年 4 月 9 日&#xff0c;Google 正式发布了 Agent2Agent&#xff08;A2A&#xff09;协议。 A2A 协议致力于打破智能体之间的隔阂&#xff0c;让它们能够跨越框架和供应商的限制&#xff0c;以一种标准化、开放的方式进行沟通与协作 截止到现在&#xff0c;代…

Ansible:roles角色

文章目录 Roles角色Ansible Roles目录编排Roles各目录作用创建 roleplaybook调用角色调用角色方法1&#xff1a;调用角色方法2&#xff1a;调用角色方法3&#xff1a; roles 中 tags 使用实战案例 Roles角色 角色是ansible自1.2版本引入的新特性&#xff0c;用于层次性、结构化…