Qt中调用thrift

news2024/11/18 14:46:09

thrift是一个Apache公司开源的一款RPC(Remote Procedure Call)框架,让不同语言构建的服务可以做到远程调用无缝对接。
thrift库分两部分:
libthrift - 核心库文件,需要依赖OpenSSL、boost
libthriftnb - 包含thrift非阻塞服务器, 需要libevent
编译环境
操作系统:windows 10
Qt:5.12.10 MinGW64
这里因为项目需要,编译MinGW64版本的thrift。Qt安装完成后将下列路径添加到环境变量:
D:\Qt\Qt5.12.10\Tools\mingw730_64\bin
D:\Qt\Qt5.12.10\5.12.10\mingw73_64\bin

一.MingW64编译boost

boost1.81.0

1.生成编译工具

加压boost源码,cmd中输入

bootstrap.bat gcc

表示使用“gcc”工具集(即我们安装的64位MingW)生成编译工具“b2.exe”

2.编译并安装boost

b2.exe install --build-type=complete threading=multi link=static address-model=64 toolset=gcc

stage表示只生成库(dll和lib),install还会生成包含头文件的include目录;
--build-type=complete表示同时生成Debug和Release版本;
threading=multi表示线程方式使用“multi ”(多线程);
link=static表示编译成静态库,shared表示编译成动态库;
address-model=64表示地址模型使用64位(即生成的库均为64位库);
toolset=gcc表示工具集使用“gcc”
可以使用b2.exe --help查看所有参数,可通过--prefix="XXXXXX"指定安装位置,如果不指定位置,默认安装到C:\Boost

二.MingW64编译OpenSSL

OpenSSL1.1.1q
下载安装msys2,我选的是最新的msys2-x86_64-20221216.exe,默认安装到C:\msys64
msys2是一个模拟的Linux命令行开发环境。msys2里本身就带了mingw,如果要用自己开发环境的mingw(也就是Qt自带的mingw,前面已添加到windows环境变量)。这里还需要在windows系统变量中创建一个变量MSYS2_PATH_TYPE,值为inherit,msys2就会继承windows系统的环境变量,去找寻windows中已经配置好的mingw工具。重新打开MSYS2 MSYS,输入gcc,没有提示找不到文件就说明刚设置的变量生效了。

如果要使用msys2自带的mingw,需要打开MSYS2 MINGW32或MSYS2 MINGW64。

经测试,这两种方式编译的OpenSSL都能正常使用。
.pro文件中添加

INCLUDEPATH += C:\msys64\home\openssl-1.1.1q\mingw64\include

LIBS += C:\msys64\home\openssl-1.1.1q\mingw64\lib\libcrypto.a \
        C:\msys64\home\openssl-1.1.1q\mingw64\lib\libssl.a

LIBS += -lWs2_32 -lCrypt32

注意要添加Ws2_32和Crypt32这两个windows库,否则很多函数找不到
下载OpenSSL,解压到C:\msys64\home\

1.配置

在openssl-1.1.1q新建mingw64文件夹,用来存放安装的文件
打开MSYS2 MINGW64,输入

cd C:/msys64/home/openssl-1.1.1q
./configure mingw64 no-shared --prefix="C:/msys64/home/openssl-1.1.1q/mingw64"

默认编译的是动态库,这里指定no-shared生成静态库
我这正常。这一步如果提示缺少perl,“/usr/bin/perl:bad interpreter:No such file or directory”,可以用指令pacman -S perl安装一个。

2.编译

make

如果提示“-bash: make: command not found”,可以用指令pacman -S make安装一个

3.安装

make install


刚进行到这一步,突然发现boost和OpenSSL可以直接安装.......,上面的内容请忽略
分割线***************************************************************************
这里是官方用MSYS2编译thrift的参考链接:https://github.com/apache/thrift/blob/master/build/cmake/README-MSYS2.md
明确指出通过这种编译方式无法生成非阻塞的服务器类型,因为libevent无法正常工作。
Note: libevent and libevent-devel do not work with this toolchain as they do not properly detect mingw64 and expect some headers to exist that do not, so the non-blocking server is not currently built into this solution.
因此,thrift传输层中的TNonblockingTransport和服务端类型中的TNonblockingServer都无法使用

thrift的协议(应用层
thrift可以让用户选择客户端与服务端之间传输通信协议的类别,在传输协议上总体划分为文本(text)和二进制(binary)传输协议。为节约带宽,提高传输效率,一般情况下使用二进制类型的传输协议为多数,有时还会使用基于文本类型的协议,这需要根据项目/产品中的实际需求。常用协议有以下几种:
TBinaryProtocol:二进制编码格式进行数据传输
TCompactProtocol:高效率的、密集的二进制编码格式进行数据传输 (常用的)
TJSONProtocol: 使用JSON文本的数据编码协议进行数据传输
TSimpleJSONProtocol:只提供JSON只写的协议,适用于通过脚本语言解析
thrift的传输层
TSocket:使用阻塞式I/O进行传输,是最常见的模式
TNonblockingTransport:使用非阻塞方式,用于构建异步客户端
TFramedTransport:使用非阻塞方式,按块的大小进行传输,类似于Java中的NIO
thrift的服务端类型
TSimpleServer:单线程服务器端,使用标准的阻塞式I/O
TThreadPoolServer:多线程服务器端,使用标准的阻塞式I/O
TNonblockingServer:单线程服务器端,使用非阻塞式I/O
THsHaServer:半同步半异步服务器端,基于非阻塞式IO读写和多线程工作任务处理
TThreadedSelectorServer:多线程选择器服务器端,对THsHaServer在异步IO模型上进行增强

一.安装编译环境

打开MSYS2 MINGW64,输入

pacman --needed -S bison flex make mingw-w64-x86_64-openssl \
                 mingw-w64-x86_64-boost mingw-w64-x86_64-cmake \
                 mingw-w64-x86_64-toolchain mingw-w64-x86_64-zlib

下载thrift源码,我选择的是最新的thrift-0.17.0,解压到C:\msys64\home

注:thrift-0.17.0.exe也要下载,然后重名为thrift.exe并添加到环境变量,待会需要用它将IDL文件转换成cpp源文件

cd C:/msys64/home/thrift-0.17.0
mkdir ../thrift-build
cd ../thrift-build
mkdir ../thrift-build
cd ../thrift-build
cmake -G"MinGW Makefiles" -DCMAKE_MAKE_PROGRAM=/mingw64/bin/mingw32-make \
   -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc.exe \
   -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++.exe \
   -DWITH_LIBEVENT=OFF \
   -DWITH_SHARED_LIB=OFF -DWITH_STATIC_LIB=ON \
   -DWITH_JAVA=OFF -DWITH_PYTHON=OFF -DWITH_PERL=OFF \
   ../thrift-0.17.0

二.编译

cmake --build .

编译成功,但是会有一个依赖NodeJS的错误,如下图所示。该错误不影响使用,因为所有的test都能测试通过。

三.运行测试

ctest

四.安装

cmake --install .

默认安装到C:\Program Files (x86)\thrift,这一步需要管理员权限,因此得用管理员权限打开MSYS2 MINGW64

五.一个例子

1.编写.thrift文件,生成cpp文件

新建文件student.thrift,输入如下内容

struct Student{
    1: i32 sno,
    2: string sname,
    3: bool ssex,
    4: i16 sage,
}
service CaoShangPa{
    void put(1: Student s),
}

打开cmd,进入student.thrift文件所在目录,执行如下命令

thrift -r --gen cpp student.thrift

生成如下5个文件
student_types.h
student_types.cpp
CaoShangPa.h
CaoShangPa.cpp
CaoShangPa_server.skeleton.cpp
其中CaoShangPa_server.skeleton.cpp是一个简单的服务端demo

2.客户端

在Qt中新建控制台工程Thrift_Client,将上面的除CaoShangPa_server.skeleton.cpp外的四个文件添加到工程中,main.cpp修改为如下所示

#include "CaoShangPa.h"
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <iostream>
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;

//using boost::shared_ptr;

int main(int argc, char **argv) {
    std::shared_ptr<TSocket> socket(new TSocket("127.0.0.1", 9090));
    std::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
    std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
    transport->open();

    Student s;
    s.sno = 123;
    s.sname = "gavin";
    s.ssex = 1;
    s.sage = 30;
    CaoShangPaClient client(protocol);
    std::cout<<"Client send a data"<<std::endl;
    std::cout<<"no:123"<<std::endl;
    std::cout<<"name:gavin"<<std::endl;
    std::cout<<"sex:1"<<std::endl;
    std::cout<<"age:30"<<std::endl;
    client.put(s);

    transport->close();
    return 0;
}

3.服务端

在Qt中新建控制台工程Thrift_Server,将上面的除CaoShangPa_server.skeleton.cpp外的四个文件添加到工程中,main.cpp修改为如下所示

#include "CaoShangPa.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include <iostream>

using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;

class CaoShangPaHandler : virtual public CaoShangPaIf {
public:
    CaoShangPaHandler() {
        // Your initialization goes here
    }

    void put(const Student& s) {
        // Your implementation goes here
        std::cout<<"Server receive a data"<<std::endl;
        std::cout<<"no:"<<s.sno<<std::endl;
        std::cout<<"name:"<<s.sname<<std::endl;
        std::cout<<"sex:"<<s.ssex<<std::endl;
        std::cout<<"age:"<<s.sage<<std::endl;
    }
};

int main(int argc, char **argv) {
    std::cout<<"Server started!"<<std::endl;
    int port = 9090;
    ::std::shared_ptr<CaoShangPaHandler> handler(new CaoShangPaHandler());
    ::std::shared_ptr<TProcessor> processor(new CaoShangPaProcessor(handler));
    ::std::shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
    ::std::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
    ::std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());

    TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
    server.serve();
    return 0;
}

4.pro文件配置

Thrift_Client.pro和Thrift_Server.pro中都要添加如下内容

INCLUDEPATH += "C:\Program Files (x86)\thrift\include" #路径中有空格要加引号
INCLUDEPATH += C:\Boost\include\boost-1_81

LIBS += -L"C:\Program Files (x86)\thrift\lib" -lthrift
LIBS += -lWs2_32

我这编译的时候会报错
C:\Program Files (x86)\thrift\include\thrift\windows\config.h:79: error: afunix.h: No such file or directory
解决方法
打开config.h,将#ifdef HAVE_AF_UNIX_H改成#ifndef HAVE_AF_UNIX_H

5.运行

先运行Thrift_Server,再运行Thrift_Client,结果如下所示

原文链接:https://blog.csdn.net/caoshangpa/article/details/128474421

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

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

相关文章

内网穿透基本使用

内网穿透基本使用 文章目录内网穿透基本使用前言一、内网穿透二、工具1.FRP2.LCX3.NPS4.Sunny-Ngork三、Sunny-ngork使用四、Frp内网穿透代理1.一层代理2.二层代理总结前言 之前零零碎碎接触过不少关于内网渗透测试、内网穿透的知识&#xff0c;但是不得不说渗透测试很吃基础、…

初学Java web(十一)AjaxAxiosJSON

Ajax&Axios&JSON 概念:AJAX(Asynchronous JavaScript And XML):异步的JavaScript和XML AJAX作用:1.与服务器进行数据交换&#xff1a;通过AJAX可以给服务器发送请求&#xff0c;并获取服务器响应的数据 使用了AJAX和服务器进行通信&#xff0c;就可以使用HTMLAJAX来替…

ArcGIS基础实验操作100例--实验10绘制带空洞的面要素

本实验专栏来自于汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 基础编辑篇--实验10 绘制带空洞的面要素 目录 一、实验背景 二、实验数据 三、实验步骤 方法一&…

【JavaScript】飞机大战简单网页版(源码下载)

文章目录一、效果演示设计思路二、鼠标版飞机大战代码展示1.HTML结构代码2.CSS样式代码3.JavaScript代码js.js文件plane.js文件三、键盘版飞机大战代码展示1.HTML结构代码2.CSS样式代码3.JavaScript代码四、代码资源分享一、效果演示 利用html&#xff0c;css&#xff0c;js制…

qt QCustomplot 用QCPItemStraightLine画参考线,阈值线,水平线

想要在两个坐标系下都画上如下参考线(阈值线&#xff0c;或者 水平线)&#xff0c; 这个参考线随着坐标轴的拖拽能够一直显示 我们找到了QCPItemStraightLine&#xff0c;该类能够画一条无限延伸的直线&#xff0c;通过下面的代码能够实现在A坐标系画一条水平线&#xff0c;但不…

[CF-EDU]Segment Tree - part 1 - Step 1 - Practice

练习名称&#xff1a;ITMO Academy: pilot course Segment Tree 练习链接&#xff1a;Segment Tree, part 1, Step1, Practice cf官方的线段树专题练习 A. Segment Tree for the Sum 单点修改&#xff0c;区间和查询 #include <bits/stdc.h> #define lson (u <&l…

P1825 [USACO11OPEN]Corn Maze S

题目描述 This past fall, Farmer John took the cows to visit a corn maze. But this wasnt just any corn maze: it featured several gravity-powered teleporter slides, which cause cows to teleport instantly from one point in the maze to another. The slides work…

Docker安装镜像,并运行成为容器

1.Docker作用 一个项目中&#xff0c;部署时需要依赖于node.js、Redis、RabbitMQ、MySQL等&#xff0c;这些服务部署时所需要的函数库、依赖项各不相同&#xff0c;甚至会有冲突。给部署带来了极大的困难。 而Docker确巧妙的解决了这些问题, Docker为了解决依赖的兼容问题的…

关于两种单菌种发酵的豆瓣酱代谢组学方面差异研究

生活离不开柴米油盐酱醋茶&#xff0c;其中酱油是中国传统的调味品&#xff0c;主要是由大豆经过发酵酿造而成。酱油由酱演变而来&#xff0c;早在三千多年前&#xff0c;中国就有制作酱的记载了。 本期百趣代谢组学文献分享为大家分享的文献是百趣生物协助客户发表的关于两种…

Git cherry-pick

Git cherry-pick 当有多个分支&#xff0c;想将一个分支 A 的提交合并到另一个分支 B 一&#xff1a;将分支A的所有提交合并到分支B&#xff0c;执行合并即可 二&#xff1a;将分支A 的某一次提交合并到分支 B&#xff0c;需要使用 git cherry-pick commit 命令 如下图&#…

随机森林-sklearn

随机森林 1.概述 1.1 集成算法概述 本身并不是一个单独的机器学习算法&#xff0c;而是通过在数据上构建多个模型&#xff0c;集成所有模型的建模结果。以此来获得最好的结果。 集成算法的目标&#xff1a; 集成算法会考虑多个评估器的建模结果&#xff0c;汇总之后得到一个…

物联网低功耗蓝牙核心配置技术: 赋能智能家居和智能工业场景

蓝牙我们都不陌生&#xff0c;早已成为深入我们生活的一项科技。不过&#xff0c;我们所知所用的还只是蓝牙的一部分。而蓝牙目前作为物联网中的一项重要通信技术&#xff0c;其应用还远远不止这些&#xff0c;今天就为大家讲讲蓝牙技术中的低功耗技术的应用及分类。 蓝牙低功耗…

原神私服搭建教程 (最新版)

搭建教程 1.准备阶段 1.请先确保电脑内有这些安装环境&#xff0c;否则私服无法运行&#xff01;&#xff01;&#xff01; MongoDB Python3.8 java17 mitmproxy 没有请在群文件下载安装环境&#xff0c;安装即可。特别强调&#xff1a;java17直接放在C:\Program Files目录下即…

初识Kubernetes:(4)Kubernetes实战入门

初识Kubernetes&#xff1a;&#xff08;4&#xff09;Kubernetes实战入门1 前言2 Namespace2.1 概述2.2 应用示例3 Pod3.1 概述3.2 语法及应用示例1 前言 介绍如何在kubernetes集群中部署一个Nginx服务&#xff0c;并且能够对其访问。 2 Namespace 2.1 概述 Namespace是ku…

写给Java程序员的GRPC入门系列(2)

点击上方GRPC专栏看完整系列 文章目录Abstract前置依赖本文初始状态编写protobuffer文件生成代码下一步Abstract 网上有很多GRPC的例子&#xff0c;但是却没有能够写给普通Java开发人员手把手入门少走弯路的教程。 本教程保证按照步骤一步步来你就可以完成GRPC从0到1的构建。 …

模型驱动PDR、数据驱动PDR实验效果对比

本学期的室内导航位置服务课程结束了&#xff0c;最后有一个结课作业做了一些工作&#xff0c;在这里分享给大家&#xff0c;同时也是自己的一个记录。 主要内容包括以下四个方面&#xff1a; 模型驱动PDR数据驱动PDR实验效果对比模型驱动PDR测试效果数据驱动PDR-RoNIN官方预训…

JSP ssh相亲网站系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 JSP ssh相亲系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发 。开发环境为TOMCAT7.0,Myeclip…

MergeTree原理之存储

我们都知道在MergeTree中数据是按列存储的&#xff0c;但是具体到存储的细节、以及如何工作的&#xff0c;都存在很多疑问。数据存储&#xff0c;就好比一本书中的文字&#xff0c;在排版时&#xff0c;绝不会密密麻麻地把文字堆满&#xff0c;这样会导致难以阅读。更为优雅的做…

Git学习:各阶段回退方法

文章目录一、问题背景二、解决方式1. 回退情况1&#xff1a;文件在工作区进行回退2. 回退情况2&#xff1a;文件在暂存区进行回退3. 回退情况3&#xff1a;文件在本地仓库进行回退4. 回退情况4&#xff1a;文件已经在远程仓库中一、问题背景 Git 是分布式的软件管理系统。在把…

代码随想录拓展day4 205. 同构字符串;1002. 查找常用字符;925.长按键入;844.比较含退格的字符串

代码随想录拓展day4 205. 同构字符串&#xff1b;1002. 查找常用字符&#xff1b;925.长按键入&#xff1b;844.比较含退格的字符串 哈希表和字符串的一些应用&#xff0c;放到一起了。 同构字符串 https://leetcode.cn/problems/isomorphic-strings/description/ 刚开始以…