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

使用 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.lryc.cn/news/470932.html

相关文章:

  • 【mysql进阶】5-事务和锁
  • 指增和中性产品的申赎加减仓及资金调拨自动化伪代码思路
  • 【论文分享】居住开放空间如何影响老年人的情感:使用可穿戴传感器的现场实验
  • 入门 | Prometheus+Grafana 普罗米修斯
  • 制作Ubuntu根文件系统
  • 16个最佳测试管理工具(2024)
  • 基于知识图谱的猕猴桃种植技术问答系统
  • Swift雨燕蜂窝无线通信系统介绍
  • 【ZZULI】数据库第二次实验
  • Javaee---多线程(一)
  • Java后端面试内容总结
  • DC-1渗透测试
  • 深度剖析:电商 API 接口如何成就卓越用户体验
  • C++调试经验:Ubuntu下CMake链接常见库的方式(持续更新)
  • 【HarmonyOS】应用实现APP国际化多语言切换
  • 使用pandas进行数据分析
  • 用于无监督域适应的提示分布对齐
  • Rust整合Elasticsearch
  • Linux 文件权限管理:chown、chgrp 和 chmod 的使用及权限掩码规则
  • 简单记录ios打包流程
  • 右键以vscode打开目录的时候出现找不到应用程序
  • 【Go-Taskflow:一个类似任务流的有向无环图(DAG)任务执行框架,集成了可视化和性能分析工具,旨在简化并行任务的复杂依赖管理】
  • 排查PHP服务器CPU占用率高的问题
  • 【学术会议论文投稿】“从零到一:使用IntelliJ IDEA打造你的梦幻HTML项目“
  • Win11安装基于WSL2的Ubuntu
  • 如何对pdf文件进行加密?pdf文件加密全攻略与深度解析(5个方法)
  • c++面向对象三大特性之一-----多态
  • 8.Linux按键驱动-中断下半部
  • Redis 线程控制 总结
  • Scrapy框架原理与使用流程