thrift一个例子

Study 10年前 (2015) ideasky
0

举一个c++的例子,简单说一下thrift的使用入门。

例子描述是这样的:我们将用户信息(学号,姓名,性别,年龄)由客户端发送到服务端。

实现这个例子,我们大致要做以下几部分事情:

(1)书写.thrift文件

(2)生成cpp文件

(3)编写客户端

(4)编译cpp文件并执行

(1)书写.thrift文件

学生信息是有结构的,所以我们使用thrift的struct即可,为了达到通信的目的,我们必须使用service。

所以最后书写成的demo.thrift文件内容如下:

struct Student1{
1:i32 id, //注意这里是逗号,而不是分号
2:string name,
3:string blurb
} //这里没有分号

service Serv{
void store(1: Student1 user), //注意这里是逗号,而不是分号
Student1 getUser(1: i32 uid)
}

(2)生成cpp文件

生成cpp文件很简单,只需要一个thrift命令即可:

thrift -r --gen cpp demo.thrift

--gen 后指定生成的语言,生成的cpp存储在目录gen-cpp下

命令执行后,将会在./gen-cpp/目录下生成如下文件:

Serv.cpp

Serv.h

Serv_server.skeleton.cpp

demo_constants.cpp

demo_constants.h

demo_types.cpp

demo_types.h

注意文件的大小写:

Serv开头的文件是由service生成的,这个关键字很重要,下面还会见到以它开头的类。

demo是根据demo.thrift文件的名生成的。

这些文件可以进行编译,生成最初的服务端。

注意:在以上文件中,只有Serv_server.skeleton.cpp是跟业务相关的,是可以修改的,其余文件都是框架相关的。

(3)编写客户端

使用thrift命令后,我们并没有得到我们想要的客户端client源代码,因此客户端程序要由我们自己编写实现。然而很幸运,我们可以使用下面的代码段来编写我们client程序:

[c]

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <protocol/TBinaryProtocol.h>
#include <transport/TSocket.h>
#include <transport/TTransportUtils.h>
#include "Serv.h"
using namespace std;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace boost;
int main(int argc, char** argv) {
shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
shared_ptr<TTransport> transport(new TBufferedTransport(socket));
shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
ServClient client(protocol);
try {
transport->open();
Student1 user;
user.id = 1;
user.name = "liqb";
user.blurb = "aaaaaa";
client.store(user);
Student1 user2;
client.getUser(user2, 1);
printf("user.id = %d user.name = %s user.blurb = %s\n", user2.id, user2.name.c_str(), user2.blurb.c_str());
transport->close();
} catch (TException &tx) {
printf("ERROR: %s\n", tx.what());
}
}

[/c]

保存成文件client.cpp

(4)编写服务端,文件(Serv_server.skeleton.cpp)只是一个框架,用户可以根据需要扩展该文件,先修改如下:

[c]</pre>
// This autogenerated skeleton file illustrates how to build a server.
// You should copy it to another filename to avoid overwriting it.

#include "Serv.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include <map>
using namespace std;

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

using boost::shared_ptr;

class ServHandler : virtual public ServIf {
public:
ServHandler() {
// Your initialization goes here
}

void store(const Student1& user) {
// Your implementation goes here
log[user.id] = user; //实际的保存操作
printf("store\n");
}

void getUser(Student1& _return, const int32_t uid) {
// Your implementation goes here
_return = log[uid]; //实际获取操作,注意:在实际生产中,这里还需要异常处理
printf("getUser\n");
}
//增加成员变量,用户保存用户数据,为了简单起见,这里只将数据保存在内存,当然可以可以保存在数据库、文件等等,主要注意,如果保存在其他介质的话
//在初始化的时候记得加载进内存或者打开访问句柄
protected:
map<int32_t, Student1> log;
};

int main(int argc, char **argv) {
int port = 9090;
shared_ptr<ServHandler> handler(new ServHandler());
shared_ptr<TProcessor> processor(new ServProcessor(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;
}
<pre>[/c]

(5)编译cpp文件并执行,注意客户端必须运行在另外一个终端里。

编译服务端:g++ -g -DHAVE_NETINET_IN_H -I. -I/usr/local/include/thrift -L/usr/local/lib Serv.cpp demo_types.cpp demo_constants.cpp Serv_server.skeleton.cpp -o server -lthrift

编译客户端:g++ -g -DHAVE_NETINET_IN_H -I/usr/local/include/thrift -L/usr/local/lib/ Serv.cpp demo_types.cpp demo_constants.cpp client.cpp -o client -lpthread -lthrift -lrt

运行服务端:./server

运行客户端:./client

 

最后编译,运行服务端,启动客户端后,服务端收到消息,显示结果为:

user.id = 1 user.name = liqb user.blurb = aaaaaa

至此,客户端已能向服务端发送数据了。

 

 

Linux下复制粘贴文件:

在命令行里,输入sudo nautilus搜索
之后输入你的用户的密码,会弹出一个目录窗口来,可以复制到这里来的,在这里也可以删掉root的文件。

清空回收站:

cd ~/.local/share/Trash/files

rm -rf *

 

版权声明:ideasky 发表于 2015-03-06 15:35:50。
转载请注明:thrift一个例子 | 梓辛小筑

暂无评论

暂无评论...