参考:
Thrift白皮书:https://blog.csdn.net/shutdown_r_now/article/details/51261124
thrift概述:https://blog.csdn.net/baidu_22254181/article/details/82814489
thrift 的原理和使用:https://www.cnblogs.com/chenny7/p/4224720.html
Thrift安装与开发:https://blog.csdn.net/colouroo/article/details/38588297
Thrift使用指南 :https://blog.csdn.net/godfrey1/article/details/78075234
使用Thrfit RPC编写程序:https://blog.csdn.net/Godfrey1/article/details/78075289
Thrift常见问题:http://www.voidcn.com/article/p-pgytobqb-bpr.html
Thrift编译:https://www.daimafans.com/article/d15930553014419456-p1-o1.html#detail-anchor-18
概述:
Thrift是一个轻量级、跨语言的远程服务调用框架,最初由Facebook开发,后面进入Apache开源项目。
它通过自身的IDL中间语言, 并借助代码生成引擎生成各种主流语言的RPC服务端/客户端模板代码。
Thrift支持多种不同的编程语言,包括C++、Java、Python、PHP、Ruby等。
Thrift软件栈分层从下向上分别为:
传输层(Transport Layer):传输层负责直接从网络中读取和写入数据,它定义了具体的网络传输协议;比如说TCP/IP传输等。
协议层(Protocol Layer):协议层定义了数据传输格式,负责网络传输数据的序列化和反序列化;比如说JSON、XML、二进制数据等。
处理层(Processor Layer):处理层是由具体的IDL(接口描述语言)生成的,封装了具体的底层网络传输和序列化方式,并委托给用户实现的Handler进行处理。
服务层(Server Layer):整合上述组件,提供具体的网络线程/IO服务模型,形成最终的服务。
一、下载与库编译
1. apatch官网下载thrift:
- thrift源码包-》thrift-0.9.3.tar.gz ,解压后编译thrift库
- thrift代码生成器-》thrift-0.9.3.exe
2.使用智能指针,下载boost并编译
3.安全通讯,下载openssl并编译
二、编写Thrift文件。记事本编写"hello.thrift"文件内容如下:
service hello{
string SayHello(1:string strName)
}
接口作用很简单:客户端传入用户名如“Tom”,服务端处理后返回给客户端"Hello,Tom"。
“service”关键字,定义服务名称。
接口函数"SayHello",有一个string类型的参数(参数前必须有编号),返回string类型的结果。
cmd进入"hello.thrift"所在目录,输入命令:thrift0.9.3.exe --gen cpp hello.thrift
则生成了对应的C++接口文件如下:
"gen-cpp"文件夹及其目录下的文件全部为自动生成。
三、建立解决方案
1.建项目Server
将第二步操作中"gen-cpp"目录中所有的文件复制到"Server"项目中。
重点关注"hello_server.skeleton.cpp",代码如下:
// This autogenerated skeleton file illustrates how to build a server.
// You should copy it to another filename to avoid overwriting it.
#include<iostream>
#include "hello.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>
#pragma comment(lib, "libthrift.lib") //添加libthrift库
#pragma comment(lib, "libeay32.lib") //添加libeay库,openSSL必需
#pragma comment(lib, "ssleay32.lib") //添加sslay库,openSSL必需
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;
using namespace std;
using boost::shared_ptr;
class helloHandler : virtual public helloIf {
public:
helloHandler() {
// Your initialization goes here
}
//原定义返回值为string
//thrift编译后,返回值为空,第一个参数作为返回值
void SayHello(std::string& _return, const std::string& strName) {
// Your implementation goes here
_return="Hello!"+strName; //修改函数体:传入参数前加"Hello",赋值给第一个参数作为返回值
cout<<"SayHello() is called!"<<endl;
//printf("SayHello\n"); //默认函数体,注释掉
}
};
int main(int argc, char **argv)
{
cout<<"Server started!"<<endl;
//以下代码均为自动生成
int port = 9090;
shared_ptr<helloHandler> handler(new helloHandler());
shared_ptr<TProcessor> processor(new helloProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
server.serve();
return 0;
}
注意2点:
a.需要添加libeay库与sslay库,否则有很多"apache::thrift::transport::initializeOpenSSL(void)"链接错误。
b.需要将Thrift源码包中的:
“TConnectedClient.h" 、"TConnectedClient.cpp"、"TServerFramework.h" 、"TServerFramework.cpp"
这几个文件添加至"Server"项目中,否则有很多“apache::thrift::server::TServerFramework::serve(void)”链接错误。
2.建项目Client
同样地,将第二步操作中"gen-cpp"目录中所有的文件(除了"hello_server.skeleton.cpp",不需要)复制到"Client"项目中。
(如客户端是Jave语言编写,则进入"hello.thrift"所在目录,输入命令:thrift0.9.3.exe --gen java hello.thrift,然后将“gen-java”目录下的文件加入java客户端项目中)
添加客户端的"main.cpp",代码如下:
#include <iostream>
#include "hello.h"
#include <boost/shared_ptr.hpp> //boost智能指针
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/transport/TSocket.h>
#pragma comment(lib, "libthrift.lib")
#pragma comment(lib, "libeay32.lib") //添加libeay库
#pragma comment(lib, "ssleay32.lib") //添加ssleay库
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;
using boost::shared_ptr;
using namespace std;
int main(int argc, char** argv)
{
int port = 9090;
//指定IP(本机)与端口
shared_ptr<TTransport> socket(new TSocket("127.0.0.1", 9090));
shared_ptr<TTransport> transport(new TBufferedTransport(socket));
shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
helloClient client(protocol);
try{
transport->open();
string strResult="";
//调用服务端接口,传入参数"Jack"
client.SayHello(strResult,"Jack");
cout<<strResult<<endl;
transport->close();
}catch(TException& tx){
printf("ERROR:%s\n",tx.what());
}
getchar();
return 0;
}
【注意】:需要添加libeay库与sslay库,否则有很多"apache::thrift::transport::initializeOpenSSL(void)"链接错误。
3.为2个项目配置头文件目录与库文件目录
thrift、 boost、 openssl头文件目录:
thrift、 boost、 openssl库文件目录:
四、测试结果
如图,3个客户端运行,接口被调用3次: