使用 Qt GRPC 构建高效的 Trojan-Go 客户端:详细指南

  • 使用 Qt GRPC 构建高效的 Trojan-Go 客户端:详细指南
    • 初识 Qt 和 gRPC
      • 什么是 Qt?
      • 什么是 gRPC?
    • 项目结构概述
    • 创建 proto 文件定义 API
      • 下载 api.proto 文件
      • 解析 proto 文件
        • 1. packageoption 语句
        • 2. 消息类型定义
          • Traffic
          • Speed
          • User
          • UserStatus
          • GetTrafficRequestGetTrafficResponse
          • ListUsersRequestListUsersResponse
          • GetUsersRequestGetUsersResponse
          • SetUsersRequestSetUsersResponse
        • 3. 服务定义
          • TrojanClientService
          • TrojanServerService
    • 配置 CMake 构建系统
      • CMake 配置解析
    • 实现 Trojan-Go 客户端
      • main.cpp 内容
      • 代码详解
      • 使用定时器实现数据流量和速度监控
    • 总结

在这里插入图片描述
trojan-go client
在这里插入图片描述

使用 Qt GRPC 构建高效的 Trojan-Go 客户端:详细指南

在上一篇 使用gRPC C++创建动态库以获取Trojan-go客户端的流量和速度信息 文章中使用纯 C++,这次随着 qt6.8 lts 发布,Qt GRPC 作为稳定模块推出,借此机会使用 Qt GRPC 实现该功能。

初识 Qt 和 gRPC

什么是 Qt?

Qt 是一个跨平台的 C++ 框架,用于开发图形界面和非图形界面应用。它提供了丰富的库支持、良好的跨平台兼容性、自动化的信号槽机制,使得在大型应用程序中管理事件和响应更为便捷。在本文中,Qt 提供了自动化工具来简化 Protobuf 和 gRPC 的代码生成,并结合 Qt 的 gRPC 模块,使得构建 gRPC 客户端更加便捷。

什么是 gRPC?

gRPC 是一种高性能的 RPC 框架,由 Google 开发,用于实现不同语言之间的服务调用。其基于 HTTP/2 协议,利用 Protocol Buffers(Protobuf)作为接口描述语言来定义服务和数据结构,允许客户端和服务器之间的轻量化通信。gRPC 的优势在于它的跨平台支持、灵活性和良好的性能,广泛应用于微服务架构和物联网领域。


项目结构概述

在创建项目之前,我们先来定义项目的目录结构,以确保文件结构清晰、便于管理:

trojan-go
├── api.proto          # Protobuf 文件,用于定义 gRPC 服务和消息格式
├── CMakeLists.txt     # CMake 构建文件,配置了编译选项、依赖项
└── main.cpp           # 主程序文件,实现客户端功能
  • api.proto:包含 API 的 gRPC 服务定义和数据结构。
  • CMakeLists.txt:配置 CMake 构建系统。
  • main.cpp:实现了 Trojan-Go 客户端的主要逻辑。

强制依赖 protoc.exe ,需要添加到环境变量中,从 https://github.com/protocolbuffers/protobuf/releases/download/v28.3/protoc-28.3-win64.zip 下载。


创建 proto 文件定义 API

proto 文件定义了客户端与服务器之间的通信规则。我们将在 api.proto 文件中定义数据结构和 gRPC 服务接口,确保客户端和服务器之间能够准确传递数据。

下载 api.proto 文件

下载 trojan-go api.proto 文件,文件内容如下:

syntax = "proto3";package trojan.api;
option go_package = "github.com/p4gefau1t/trojan-go/api/service";message Traffic {uint64 upload_traffic = 1;uint64 download_traffic = 2;
}message Speed {uint64 upload_speed = 1;uint64 download_speed = 2;
}message User {string password = 1;string hash = 2;
}message UserStatus {User user = 1;Traffic traffic_total = 2;Speed speed_current = 3;Speed speed_limit = 4;int32 ip_current = 5;int32 ip_limit = 6;
}message GetTrafficRequest {User user = 1;
}message GetTrafficResponse {bool success = 1;string info = 2;Traffic traffic_total = 3;Speed speed_current = 4;
}message ListUsersRequest {}message ListUsersResponse {UserStatus status = 1;
}message GetUsersRequest {User user = 1;
}message GetUsersResponse {bool success = 1;string info = 2;UserStatus status = 3;
}message SetUsersRequest {enum Operation {Add = 0;Delete = 1;Modify = 2;}UserStatus status = 1;Operation operation = 2;
}message SetUsersResponse {bool success = 1;string info = 2;
}service TrojanClientService {rpc GetTraffic(GetTrafficRequest) returns(GetTrafficResponse){}
}service TrojanServerService {// list all usersrpc ListUsers(ListUsersRequest) returns(stream ListUsersResponse){}// obtain specified user's inforpc GetUsers(stream GetUsersRequest) returns(stream GetUsersResponse){}// setup existing users' configrpc SetUsers(stream SetUsersRequest) returns(stream SetUsersResponse){}
}
解析 proto 文件

这个 api.proto 文件定义了用于 Trojan API 的 gRPC 服务和消息结构,描述了客户端与服务器之间的通信模式。以下是该文件的详细解释:

1. packageoption 语句
package trojan.api;
option go_package = "github.com/p4gefau1t/trojan-go/api/service";
  • package 声明了 proto 文件的包名,trojan.api 用于在生成的代码中作为命名空间。
  • option go_package 定义了用于 Go 语言生成代码的包名,便于 Go 项目中导入。
2. 消息类型定义
Traffic
message Traffic {uint64 upload_traffic = 1;uint64 download_traffic = 2;
}
  • Traffic 消息定义了用户的上传和下载流量,字段类型为 uint64 表示无符号 64 位整数,适合表示较大的流量数据。
Speed
message Speed {uint64 upload_speed = 1;uint64 download_speed = 2;
}
  • Speed 消息记录了上传和下载速度,同样使用 uint64 类型来表示。
User
message User {string password = 1;string hash = 2;
}
  • User 消息包含用户的密码和哈希值,用于用户身份验证或标识。
UserStatus
message UserStatus {User user = 1;Traffic traffic_total = 2;Speed speed_current = 3;Speed speed_limit = 4;int32 ip_current = 5;int32 ip_limit = 6;
}
  • UserStatus 消息表示用户的状态信息,包含用户数据 (User)、总流量 (Traffic)、当前和限制速度 (Speed)、当前和限制的 IP 数量。
GetTrafficRequestGetTrafficResponse
message GetTrafficRequest {User user = 1;
}message GetTrafficResponse {bool success = 1;string info = 2;Traffic traffic_total = 3;Speed speed_current = 4;
}
  • GetTrafficRequest 包含 User 数据,用于请求流量信息。
  • GetTrafficResponse 返回请求状态 success、信息 info,以及流量数据和速度数据。
ListUsersRequestListUsersResponse
message ListUsersRequest {}message ListUsersResponse {UserStatus status = 1;
}
  • ListUsersRequest 不含字段,用于请求用户列表。
  • ListUsersResponse 返回每个用户的状态信息。
GetUsersRequestGetUsersResponse
message GetUsersRequest {User user = 1;
}message GetUsersResponse {bool success = 1;string info = 2;UserStatus status = 3;
}
  • GetUsersRequest 请求特定用户的信息。
  • GetUsersResponse 返回状态 success、信息 info 和用户状态 UserStatus
SetUsersRequestSetUsersResponse
message SetUsersRequest {enum Operation {Add = 0;Delete = 1;Modify = 2;}UserStatus status = 1;Operation operation = 2;
}message SetUsersResponse {bool success = 1;string info = 2;
}
  • SetUsersRequest 包含 UserStatusOperation,用于增加、删除或修改用户。
  • SetUsersResponse 返回操作状态 success 和相关信息 info
3. 服务定义
TrojanClientService
service TrojanClientService {rpc GetTraffic(GetTrafficRequest) returns(GetTrafficResponse){}
}
  • 定义 GetTraffic RPC 方法,允许客户端请求其流量信息。
TrojanServerService
service TrojanServerService {// list all usersrpc ListUsers(ListUsersRequest) returns(stream ListUsersResponse){}// obtain specified user's inforpc GetUsers(stream GetUsersRequest) returns(stream GetUsersResponse){}// setup existing users' configrpc SetUsers(stream SetUsersRequest) returns(stream SetUsersResponse){}
}
  • TrojanServerService 包含 3 个方法:
    • ListUsers:返回用户列表,使用数据流式响应。
    • GetUsers:获取特定用户信息,支持流式请求和响应。
    • SetUsers:修改用户信息,通过流式请求和响应实现。

这个 api.proto 文件定义了 Trojan API 的服务与数据结构,支持流量查询、用户信息获取、用户列表和配置管理等功能。


配置 CMake 构建系统

接下来在 CMakeLists.txt 文件中配置 CMake,以便编译和链接所需的库和依赖。

cmake_minimum_required(VERSION 3.16)
project(trojan-go LANGUAGES CXX)set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Protobuf Grpc)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Protobuf Grpc)add_executable(client main.cpp)qt_add_protobuf(clientPROTO_FILESapi.proto
)qt_add_grpc(client CLIENTPROTO_FILESapi.proto
)include(GNUInstallDirs)
install(TARGETS clientLIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
CMake 配置解析
  • qt_add_protobufqt_add_grpc 用于生成 Protobuf 和 gRPC 的 C++ 代码。
  • install 指定安装路径,将可执行文件安装到系统的标准目录。

实现 Trojan-Go 客户端

main.cpp 文件实现了客户端的主要逻辑,负责与服务器通信并处理流量信息。

main.cpp 内容
#include <QCoreApplication>
#include <QTimer>
#include <memory>
#include "api.qpb.h"
#include "api_client.grpc.qpb.h"
#include <QGrpcHttp2Channel>
#include <QGrpcChannelOptions>
#include <QGrpcStatus>
#include <QGrpcCallReply>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);trojan::api::TrojanClientService::Client client;QGrpcChannelOptions channelOptions;QUrl clientApi = QUrl("http://127.0.0.128:10000"/*用户设定的 trojan-go api 地址和端口*/, QUrl::StrictMode);std::shared_ptr<QGrpcHttp2Channel> channel = std::make_shared<QGrpcHttp2Channel>(clientApi, channelOptions);if(client.attachChannel(channel)) {qDebug() << "attachChannel success";} else {qDebug() << "attachChannel failed";};QTimer timer;QObject::connect(&timer, &QTimer::timeout, &a, [&]() {trojan::api::User user;user.setPassword("trojan-go.com"/*用户连接服务器的密码*/);trojan::api::GetTrafficRequest req;req.setUser(user);std::unique_ptr<QGrpcCallReply> reply = client.GetTraffic(req);auto *replyPtr = reply.get();QObject::connect(replyPtr,&QGrpcCallReply::finished,&a,[reply = std::move(reply)](const QGrpcStatus &status) {if(!status.isOk()) {qDebug() << "Failed to send message: " << status;} else {trojan::api::GetTrafficResponse response;if(reply->read(&response)) {qDebug() << "Success:" << response.success();qDebug() << "Info:" << response.info();double downloadTrafficMB = response.trafficTotal().downloadTraffic() / 1024.0 / 1024.0;double uploadTrafficMB   = response.trafficTotal().uploadTraffic() / 1024.0 / 1024.0;double downloadSpeedMBps = response.speedCurrent().downloadSpeed() / 1024.0 / 1024.0;double uploadSpeedMBps   = response.speedCurrent().uploadSpeed() / 1024.0 / 1024.0;qDebug() << QString("Download Traffic: %1 MB").arg(downloadTrafficMB, 0, 'f', 2);qDebug() << QString("Upload Traffic: %1 MB").arg(uploadTrafficMB, 0, 'f', 2);qDebug() << QString("Download Speed: %1 MB/s").arg(downloadSpeedMBps, 0, 'f', 2);qDebug() << QString("Upload Speed: %1 MB/s").arg(uploadSpeedMBps, 0, 'f', 2);qDebug() << "";} else {qDebug() << "Failed to parse GetTrafficResponse.";}}},Qt::SingleShotConnection);});timer.start(500);return a.exec();
}
代码详解
  • 连接服务器:使用 QGrpcHttp2Channel 通过 HTTP/2 连接到服务器。
  • 定时器监控:每 500 毫秒发送一次 GetTraffic 请求以获取最新流量和速度统计数据。
  • 结果解析和输出:解析服务器返回的流量数据并输出到控制台。
使用定时器实现数据流量和速度监控

通过 Qt 的 QTimer 实现客户端定时请求服务器流量和速度统计数据并进行处理。在实际应用中,定时更新数据可以实时监控服务器的状态,有助于及时获取连接信息并检测异常。


总结

本文介绍了如何使用 Qt 和 gRPC 实现一个高效的 Trojan-Go 客户端。从环境配置、Protobuf 文件定义、CMake 构建配置到主程序逻辑,我们全面讲解了客户端实现的每一步骤。借助 Qt 和 gRPC 的自动化工具,开发者能够更高效地实现客户端应用,同时享受 gRPC 高效的通信和 Qt 的跨平台支持。这一项目展示了 gRPC 的强大应用场景,也为开发更复杂的网络应用打下了基础。

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

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

相关文章

CI/CD 的原理

一、CI/CD 的概念 CI/CD是一种软件开发流程&#xff0c;旨在通过自动化和持续的集成、测试和交付实现高质量的软件产品。 CI(Continuous Integration)持续集成 目前主流的开发方式是协同开发&#xff0c;即多位开发人员同事处理同意应用不同模块或功能。 如果企业在同一时间将…

LabVIEW开发的控制阀监控与维护系统

LabVIEW开发一套自动测试软件&#xff0c;用于控制阀的实时监控、数据采集、维护管理以及报警通知。此系统的目标是通过便捷的操作界面、可靠的通信接口和高效的数据管理&#xff0c;为工厂设备管理提供全面的支持。 1. 项目需求 目标是实现一个控制阀管理系统&#xff0c;能够…

采用STM32CubeMX和HAL库的外部中断设计实例

目录 STM32F1外部中断的硬件设计 STM32F1外部中断的软件设计 通过Keil MDK实现工程 通过Keil MDK实现工程的步骤如下&#xff1a; 中断在嵌入式应用中占有非常重要的地位&#xff0c;几乎每个控制器都有中断功能。中断对保证紧急事件在第一时间处理是非常重要的。 设计使用外…

Python酷库之旅-第三方库Pandas(173)

目录 一、用法精讲 796、pandas.Float32Dtype类 796-1、语法 796-2、参数 796-3、功能 796-4、返回值 796-5、说明 796-6、用法 796-6-1、数据准备 796-6-2、代码示例 796-6-3、结果输出 797、pandas.Float64Dtype类 797-1、语法 797-2、参数 797-3、功能 797-…

Bi-LSTM-CRF实现中文命名实体识别工具(TensorFlow)

项目源码获取方式见文章末尾&#xff01; 回复暗号&#xff1a;13&#xff0c;免费获取600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 **《------往期经典推荐------》**项目名称 1.【MobileNetV2实现实时口罩检测tensorflow】 2.【卫星图像道路检测DeepLabV3P…

AI 聊天机器人的兴起:GPT-3 和 BERT 如何重新定义对话体验

一、说明 当我们深入研究 AI 世界时&#xff0c;了解自然语言处理 &#xff08;NLP&#xff09; 领域取得的巨大进步非常重要。NLP 是 AI 的一个分支&#xff0c;专注于使计算机能够理解、解释和生成人类语言。GPT-3 和 BERT 等语言模型的开发是这一旅程中的一个重要里程碑&…

1FreeRTOS学习(队列、二值信号量、计数型信号量之间的相同点和不同点)

相同点&#xff1a; &#xff08;1&#xff09;传递区间 队列、二值信号量、计数型信号量均可用在任务与任务&#xff0c;任务与中断之间进行消息传递 &#xff08;2&#xff09; 传递方式 创建队列--发送队列--接受队列 创建二值信号量--发送二值信号量--接受二值信号量 创建计…

UDP(用户数据报协议)端口监控

随着网络的扩展&#xff0c;确保高效的设备通信对于优化网络功能变得越来越重要。在这个过程中&#xff0c;端口发挥着重要作用&#xff0c;它是实现外部设备集成的物理连接器。通过实现数据的无缝传输和交互&#xff0c;端口为网络基础设施的顺畅运行提供了保障。端口使数据通…

技术成神之路:设计模式(二十三)解释器模式

相关文章&#xff1a;技术成神之路&#xff1a;二十三种设计模式(导航页) 介绍 解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为设计模式&#xff0c;用于定义一种语言的文法表示&#xff0c;并提供一个解释器来处理这种文法。它用于处理具有特定语法或表达…

STM32G4 双ADC模式之同时注入模式

目录 概述 1 认识双ADC模式 2 功能实现 2.1 功能介绍 2.2 实现原理 概述 本文主要介绍STM32G4 双ADC模式之同时注入模式的相关内容&#xff0c;包括ADC模块的功能介绍&#xff0c;实现框架结构&#xff0c;以及注入模式ADC的转换的实现原理。 1 认识双ADC模式 双ADC模式可…

Python数据分析NumPy和pandas(十五、pandas 数据加载、存储和文件格式)

大多数时候&#xff0c;我们要处理分析的数据是存储在不同格式的文件中的&#xff0c;有txt、csv、excel、json、xml以及二进制等磁盘文件格式&#xff0c;还有时候是从数据库以及从Web API中交互获取要处理的数据。现在开始学习如何用pandas从以上内容中输入和输出数据。 读取…

CRC校验 生成多项式选取奇次偶次的问题讨论

目录 问题一&#xff1a;为什么CRC校验码不支持偶次校验码&#xff1f; 问题二&#xff1a;如何判断一个生成多项式是否为偶次多项式&#xff1f; 步骤&#xff1a; 示例&#xff1a; 注意&#xff1a; 问题三&#xff1a;CRC32的生成多项式是什么&#xff1f;是偶次还是…

Docker 常用命令全解析:提升对雷池社区版的使用经验

Docker 常用命令解析 Docker 是一个开源的容器化平台&#xff0c;允许开发者将应用及其依赖打包到一个可移植的容器中。以下是一些常用的 Docker 命令及其解析&#xff0c;帮助您更好地使用 Docker。 1. Docker 基础命令 查看 Docker 版本 docker --version查看 Docker 运行…

python 爬虫 入门 五、抓取图片、视频

目录 一、图片、音频 二、下载视频&#xff1a; 一、图片、音频 抓取图片的手法在上一篇python 爬虫 入门 四、线程&#xff0c;进程&#xff0c;协程-CSDN博客里面其实有&#xff0c;就是文章中的图片部分&#xff0c;在那一篇文章&#xff0c;初始代码的28&#xff0c;29行…

保姆级教程 | 全流程免费:合并多份长宽不同的PDF成相同大小并进行瘦身

背景 由于老板需要&#xff0c;完成不同PDF文件&#xff08;a&#xff0c;b&#xff0c;c....&#xff09;合并&#xff0c;同时要求主文件&#xff08;A&#xff09;小于6M。合并过程中发现各个PDF大小&#xff08;长宽&#xff09;并不相同&#xff0c;造成合并后效果不好也…

Vue3 学习笔记(八)Vue3 语法-Class 与 Style绑定详解

在 Vue.js 中&#xff0c;动态地绑定 CSS 类和样式是一项常见的需求。Vue 提供了几种不同的方法来实现这一点&#xff0c;包括对象语法、数组语法和组件的作用域插槽。 以下是这些方法的详细说明&#xff1a; 一、Class 绑定 1、对象语法 对象语法允许根据表达式的真值动态地切…

java知识管理系统源码(springboot)

项目简介 知识管理系统实现了以下功能&#xff1a; 知识管理系统的主要使用者分为管理员和用户两个角色。管理员功能有个人中心&#xff0c;用户管理&#xff0c;文章分类管理&#xff0c;文章信息管理&#xff0c;资料分类管理&#xff0c;资料下载管理&#xff0c;问答管理…

信捷 PLC C语言 定时器在FC中的使用

传统梯形图的定时器程序写起来简单&#xff0c;本文用C语言写定时器的使用。 定时器在c语言中使用&#xff0c;和普通梯形图中使用的区别之一是既有外部条件&#xff0c;也有内部条件。 1.建全局变量 2.建立FC POU 这个是功能POU程序。 这里的Enable是内部条件 3.调用包含定…

重写(外壳不变)

重写&#xff1a;是子类对父类非静态、非private修饰、非final修饰、非构造方法等的实现过程进行重新编写返回值和形参都不能改变。 重写的好处&#xff1a;子类可以根据需要&#xff0c;定义专属于自己的行为。&#xff08;子类能够根据需要实现父类的方法&#xff09; 方法…

大数据日志处理框架ELK方案

介绍应用场景大数据ELK日志框架安装部署 一&#xff0c;介绍 大数据日志处理框架ELK&#xff08;Elasticsearch、Logstash、Kibana&#xff09;是一套完整的日志集中处理方案&#xff0c;以下是对其的详细介绍&#xff1a; 一、Elasticsearch&#xff08;ES&#xff09; 基本…