首页 > 编程语言 >Thrift C++

Thrift C++

时间:2023-12-28 16:48:24浏览次数:46  
标签:TSocket ping C++ cpp Thrift transport thrift

一、引子

Thrift is an interface definition language and binary communication protocol that is used to define and create services for numerous languages.

Thrift是用于...(使用接口定义语言和二进制通信协议定义并创建跨语言服务) 的框架,允许开发者在不同的编程语言之间通信。

二、安装(OS: ubuntu18.04/ubuntu20.04/ubuntu22.04; Thrift: 0.20.0)

0. 更新包管理器

sudo apt update

1. 安装依赖

sudo apt install -y build-essential automake bison flex pkg-config libboost-all-dev linssl-dev

  1) bison: Bison(GNU Bison)是一个用于生成解析器的工具。

  2) flex:Flex(Fast Lexical Analyzer Generator)是一个用于生成词法分析器的工具。

  3) libboost-all-dev:是 Boost C++ 库的开发包,包含了 Boost 库的所有开发文件和头文件。

  4) libssl-dev:是 OpenSSL 库的开发包,它包含了 OpenSSL 库的头文件和用于开发的其他文件。

  其余依赖较为常见。

2. 获取下载源码

wget http://apache.mirror.gtcomm.net/thrift/0.15.0/thrift-0.15.0.tar.gz

3. 解压缩文件

tar -xvzf thrift-0.15.0.tar.gz

4. 进入目录,配置并构建

cd thrift-0.20.0
./configure
make

5. 安装Thrift

sudo make install

三、案例

1. 开发流程

  1)按照需求编写thrift接口定义文件

  2)利用thrift binary为不同的语言生成代码

  3)根据需求,修改生成的代码(Server端代码),以编写实际的业务逻辑

  4)编写客户端代码,编译,集成。

2. rpc

  1)创建目录并创建ping.thrift

mkdir thrift_ping
cd thrift_ping
touch ping.thrift

  2)编写ping.thrift,其内容如下所示:

# ping.thrift

/**
 * Thrift files can namespace, package, or prefix their output in various
 * target languages
 */

namespace cpp pingtest

/**
 * Defining a class named pinger
 */

service pinger {
    /**
     * client calls ping method to make sure service process is active or dead
     */
    void ping()
}

  3)生成服务器端模板代码

thrift --gen cpp -o . ping.thrift

  主要服务器端的模板代码并不涉及业务,因此需要自己按需编写server端代码(仅作演示可用gen-cpp/pinger_server.skeleton.cpp)。

  4)编译server端可执行文件

cp gen-cpp/* .
g++ -g -Wall -std=c++11 -I/usr/local/include -L/usr/local/lib ./*.cpp -o server -lthrift

  5)编写客户端 client.cpp ,其内容如下所示:

#include <iostream>

#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>

#include "pinger.h"

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

using namespace pingtest;

int main() {
    std::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
    std::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
    std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
    pingerClient client(protocol);

    try {
        transport->open();

        client.ping();

        transport->close();
    } catch (TException& tx) {
        std::cout << "ERROR: " << tx.what() << std::endl;
    }

    return 0;
}

  6)编译客户端代码

g++ -g -Wall -std=c++11 client.cpp pinger.cpp -o client -lthrift

  7)打开两个终端界面

    1--运行服务器端,打开监听端口

./server

    2--运行客户端,每运行一次,服务器端打印一遍"ping"

./client

  **可自行尝试在两台服务器上运行上述代码,主要修改服务器端口中TSocket的地址信息为服务器的地址信息(IP地址),前提:两台设备可以相互ping通。**

3. 数据传输--与rpc差不多,不过有传递数据而已。

可参考以下博客(抱歉这里的拿来主义,偷点懒,若遇到环境问题,可留言)

技术: Thrift | 梅林日志 (wizardmerlin.github.io)

四、架构

 从下往上依次是(有不同意见可指出来,十分欢迎):

  1. 传输层

    实际的数据传输发生在传输层。Thrift 提供了多种传输层协议,例如 TSocket、TFramedTransport、TBufferedTransport 等,用于在客户端和服务端之间传输数据。

  2. 协议层

    协议层定义了数据的序列化和反序列化规则,使得不同语言和平台之间可以有效地交换数据。Thrift 支持多种协议,包括 TBinaryProtocol、TJSONProtocol、TCompactProtocol 等。

  3. 数据结构层

    结构体、异常和集合:在Thrift中,可以定义结构体、集合和异常等数据结构。这些数据结构用于在服务器之间传输数据,且支持嵌套结构。

  4. 服务层

    Thrift服务:定义了在客户端和服务器之间远程调用的服务接口。通过 IDL 文件定义的服务接口在编译过程中生成对应的客户端和服务器代码,使得不同语言的应用能够通过这些服务进行通信。

  5. 编译器层

    Thrift编译器:IDL文件需要经过Thrift层处理。Thrift编译器将IDL文件转换为不同编程语言的代码,生成用于序列化和反序列化数据以及调用远程服务的代码。

  6. IDL(Interface Definition Layer)层

    IDL文件:首先定义了接口层的规范,这是通过使用IDL文件完成的。IDL文件描述了要在不同语言之间传输的数据结构和服务接口。

五、详细说明

  1. Thrift支持的数据结构

    1)基本数据类型

    •   bool: 布尔类型,取值为 truefalse
    •   byte: 8 位带符号整数。
    •   i16: 16 位带符号整数。
    •   i32: 32 位带符号整数。
    •   i64: 64 位带符号整数。
    •   double: 双精度浮点数。
    •   string: 字符串。

    2)结构体:结构体是一种用户定义的数据结构,可以包含多个字段。每个字段都有自己的类型和名称。

struct Person {
1: i32 id,
2: string name,
3: bool isStudent
}

    3)异常:异常是一种特殊的结构体,用于表示错误或异常情况。它们通常用于在服务调用过程中传递错误信息。

exception MyException {
  1: i32 errorCode,
  2: string errorMessage
}

    4)集合:支持列表、集合和映射等集合类型。

list<i32> intList;
set<string> stringSet;
map<string, double> stringToDoubleMap;

    5)枚举:枚举是一种有限的、命名的整数类型,表示一组相关的常量。

enum Color {
  RED = 1,
  GREEN = 2,
  BLUE = 3
}

    6)服务接口:服务接口定义了一组相关的远程过程调用(RPC)方法,客户端可以调用这些方法来与服务端进行通信。

service MyService {
  i32 add(1: i32 a, 2: i32 b),
  string concatenate(1: string str1, 2: string str2)
}

  2. Thrift支持的协议

    1)TBinaryProtocol:二进制协议,使用二进制格式对数据进行序列化。这是 Thrift 默认的协议,提供了高效的序列化和压缩。

    2)TCompactProtocol:紧凑协议,使用变长编码对数据进行序列化,以减小数据包的大小。适用于带宽受限的网络环境。

    3)TJSONProtocol:JSON 协议,将数据序列化为 JSON 格式。适用于调试和与其他应用程序集成,但相对于二进制协议而言,JSON 格式会更大、更慢。

    4)TSimpleJSONProtocol:简单的 JSON 协议,与 TJSONProtocol 类似,但生成的 JSON 格式更为简单,适用于人类可读的场景。

    5)TDebugProtocol:调试协议,生成可读的文本输出,适用于调试目的。

  3. Thrift支持的传输层

    1)TSocket:使用传统的 TCP Socket 进行通信。通常用于在同一台机器上的进程之间或在网络上进行传输。

transport = TSocket(host, port)

    2)TFramedTransport:在数据传输之前,在每个消息的开头添加消息的长度信息。这样可以确保接收方能够正确地解析每个消息。

transport = TFramedTransport(TSocket(host, port))

    3)TBufferedTransport:缓冲传输,提供了一个缓冲区,可以在数据传输之前缓冲一定量的数据,以减少网络交互的次数。

transport = TBufferedTransport(TSocket(host, port))

    4)TZlibTransport:使用 zlib 压缩数据,可以减小数据传输的大小,适用于带宽受限的网络环境。

transport = TZlibTransport(TSocket(host, port))

    5)TMemoryBuffer:在内存中缓存数据,用于本地进程之间的通信,或者在需要对数据进行多次操作时。

transport = TMemoryBuffer()

    6)TFileTransport:文件传输,用于通过文件进行数据传输。适用于大量数据的离线传输场景。

transport = TFileTransport(file)

    7)TFastFramedTransport:类似于 TFramedTransport,但使用了更加紧凑的帧格式,适用于带宽敏感的场景。

transport = TFastFramedTransport(TSocket(host, port))

六、源码分析

  以后吧.......

七、参考博客

  1.  Archives | 梅林日志 (wizardmerlin.github.io)

  2.  Apache Thrift系列详解(一) - 概述与入门 - 知乎 (zhihu.com)

  3. Thrift - 维基百科,自由的百科全书 (wikipedia.org)

标签:TSocket,ping,C++,cpp,Thrift,transport,thrift
From: https://www.cnblogs.com/hjxiamen/p/17932740.html

相关文章

  • 【C++】使用指针,动态多维数组
    二维数组intm=3,n=2;int**arr;//动态创建二维数组[3][2]arr=newint*[m];//这里是mfor(inti=0;i<m;i++){ arr[i]=newint[n];//这里是n}三维数组intx=3,y=4,z=5;//arr[3][4][5]int***arr;arr=newint**[x];for(inti=0;i<x;i++){......
  • [C++ 从入门到精通] 17.基类与派生类关系的详细再探讨
    文章预览:一.派生类对象模型简述二.派生类构造函数三.既当父类又当子类(多继承)四.不想当基类的类final五.静态类型与动态类型六.派生类向基类的隐式类型转换七.父类子类之间的拷贝与赋值一.派生类对象模型简述若一个类,继承自一个父类(基类),那么该类称之为子类(派生类)。并且该......
  • [C++ 从入门到精通] 18.左值、右值,左值引用、右值引用、move
    文章预览:一.左值和右值二.引用分类三.左值引用(1个地址符&)四.右值引用(2个地址符&)五.std::move函数一.左值和右值inti;//赋值语句i=20;//左值:i(int类型的对象,代表一块内存区域),右值:20(代表一个值)左值(左值表达式):能用在赋值语句等号左侧的东西,就称之为左值。它能够代表一个......
  • [C++ 从入门到精通] 16.RTTI、dynamic_cast、typeid、虚函数表
    文章预览:一.RTTI是什么二.dynamic_cast类型(指针/引用)转换2.1C风格的强制类型转换2.2指针转换(常见用法)2.3引用转换三.typeid运算符四.type_info类五.RTTI与虚函数表一.RTTI是什么RTTI(Run-TimeTypeIdentification):通过运行时类型信息,程序能够使用基类的指针或引用来检查......
  • [C++ 从入门到精通] 15.友元函数、友元类、友元成员函数
    文章预览:一.前言二.友元函数三.友元类四.友元成员函数一.前言众所周知,C++控制对类对象私有成员的访问。通常,公有类方法(public)提供唯一的访问途径,但是有时候这种限制太严格,以至于不适合特定的编程问题。在这种情况下,C++提供了另外一种形式的访问权限:友元,友元有3种:友元函数;友......
  • 人体关键点检测4:C/C++实现人体关键点检测(人体姿势估计)含源码 可实时检测OpenCV库使
    人体关键点检测4:C/C++实现人体关键点检测(人体姿势估计)含源码可实时检测目录人体关键点检测4:C/C++实现人体关键点检测(人体姿势估计)含源码可实时检测1.项目介绍2.人体关键点检测方法(1)Top-Down(自上而下)方法(2)Bottom-Up(自下而上)方法:3.人体关键点检测模型(1)人体关键点检测......
  • 一键抠图2:C/C++实现人像抠图 (Portrait Matting)OpenCV库使用opencv-4.3.0版本,opencv_
    一键抠图2:C/C++实现人像抠图(PortraitMatting)目录一键抠图2:C/C++实现人像抠图(PortraitMatting)1.前言2.抠图算法3.人像抠图算法MODNet(1)模型训练(2)将Pytorch模型转换ONNX模型(3)将ONNX模型转换为TNN模型4.模型C++部署(1)项目结构(2)配置开发环境(OpenCV+OpenCL+base-utils+TNN)(3)......
  • 手部关键点检测5:C++实现手部关键点检测(手部姿势估计)含源码 可实时检测OpenCV库使用o
    手部关键点检测5:C++实现手部关键点检测(手部姿势估计)含源码可实时检测目录手部关键点检测4:C++实现手部关键点检测(手部姿势估计)含源码可实时检测1.项目介绍2.手部关键点检测(手部姿势估计)方法(1)Top-Down(自上而下)方法(2)Bottom-Up(自下而上)方法:3.手部关键点检测模型(1)手部......
  • IM通讯协议专题学习(十):初识 Thrift 序列化协议
    本文由字节跳动技术团队杨晨曦分享,本文有修订和改动。1、引言本文将带你一起初步认识Thrift的序列化协议,包括Binary协议、Compact协议(类似于Protobuf)、JSON协议,希望能为你的通信协议格式选型带来参考。  技术交流:-移动端IM开发入门文章:《新手入门一篇就够:......
  • C++ --- 函数模板
    函数模板C++的一种编程思想称为泛型编程,主要利用的技术就是模板。编写与类型无关的调用代码,是代码复用的一种手段。 模板是泛型编程的基础。C++提供两种模板机制:函数模板和类模板。函数模板:建立一个通用的函数,它用到的参数类型可以不确定,用一个虚拟类型替代。等到函数调用的时......