现在的位置: 首页 > 综合 > 正文

【学习笔记】thrift下载与安装

2014年07月20日 ⁄ 综合 ⁄ 共 3712字 ⁄ 字号 评论关闭

一、简介

thrift来自于facebook,是一个软件框架,用来进行可扩展且跨语言的服务的开发。允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。它可支持 C++、
Java,、Python,、PHP、C#等等一些主流的语言,类似于Google的protobuf,关于两者之间的比较网上也有很多,还有一个后起之秀avro有hadoop的背景,也值得关注。由于我最早接触的是thrift,因此一直都在使用这个,而且已在几个项目中使用了,没出现过什么问题,因此也没心思去研究protobuf和avro了。

二、下载与安装

环境:Ubuntu

依赖:boost、libevent

下载地址:http://thrift.apache.org/download/

下载文件:thrift-0.9.0.tar.gz

我用的是Ubuntu,按照官网给出的安装步骤安装没什么问题,主要是要依赖boost和libevent,把这两个装好就可以。可直接使用官网给的命令:

sudo apt-get install libboost-dev libboost-test-dev libboost-program-options-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev

由于我常用boost开发,已经安装过了boost,因此直接连接过去就可以。

$>tar xvf thrift-0.9.0.tar.gz
$>ch thrift-0.9.0
$>./config --prefix=/usr/local/thrift --with-boost=/usr/local/boost
$>make
$>make install

三、测试

直接使用官网的例子

1.编写代码生成脚本文件

UserStorage.thrift(注:后缀必须是thrift,文件名会生成类名)

struct UserProfile {
    1: i32 uid,
    2: string name,
    3: string blurb
}
service UserStorage {
     void store(1: UserProfile user),
     UserProfile retrieve(1: i32 uid)
}

要将$THRIFT_HOME/bin加入环境变量的PATH中,然后执行命令:

$>thrift -gen cpp UserStorage.thrift

这是当前目录下会有个gen-cpp的目录,里面包含了生成的相关C++代码(也可以通过thrift命令生成其它代码,如:thrift -gen java UserStorage.thrift ,这样就生成了java代码):

UserStorage.h

UserStorage.cpp

UserStorage_types.h
UserStorage_types.cpp

UserStorage_constants.h

UserStorage_constants.cpp

UserStorage_server.skeleton.cpp
上面标红的文件是我们这个例子所需的代码,另外三个可暂时不用管。

2.编写服务器端代码

server.cpp

#include <iostream>
#include <boost/shared_ptr.hpp>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/server/TSimpleServer.h>
#include "UserStorage.h"
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;
using namespace apache::thrift::server;
using namespace apache::thrift::concurrency;
using namespace boost;

class UserStorageHandler : virtual public UserStorageIf {
public:
	UserStorageHandler() {
		// Your initialization goes here
	}

	void store(const UserProfile& user) {
		// Your implementation goes here
		printf("store\n");
	}

	void retrieve(UserProfile& _return, const int32_t uid) {
		// Your implementation goes here
		printf("retrieve\n");
	}
};

int main(int argc, char **argv) {
	int port = 9090;
	shared_ptr handler(new UserStorageHandler());
	shared_ptr processor(new UserStorageProcessor(handler));
	shared_ptr serverTransport(new TServerSocket(port));
	shared_ptr transportFactory(new TBufferedTransportFactory());
	shared_ptr protocolFactory(new TBinaryProtocolFactory());
	TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
	server.serve();
	return 0;
}

g++ -o server -I/usr/local/boost/include -I/usr/local/thrift/include -L/usr/local/boost/lib -L/usr/local/thrift/lib -lthrift -lthriftnb -levent server.cpp


3.客户端代码

client.cpp


#include <iostream>
#include <boost/shared_ptr.hpp>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/protocol/TProtocol.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include "UserStorage.h"

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

int main()
{
	boost::shared_ptr<TTransport> m_sock;
	boost::shared_ptr<TTransport> m_pTransport;
	boost::shared_ptr<TProtocol> m_protocol;
	shared_ptr<UserStorageClient> m_pClient;
	m_sock.reset(new TSocket("127.0.0.1", 9090));
	m_pTransport.reset(new TFramedTransport(m_sock));
	m_protocol.reset(new TBinaryProtocol(m_pTransport));
	m_pClient.reset(new UserStorageClient(m_protocol));
	m_pTransport->open();
	UserProfile up;
	up.uid = 1;
	up.name = "bocheng";
	up.blurb = "1";
	m_pClient->store(up);
	return 0;
}

g++ -o client -I/usr/local/boost/include -I/usr/local/thrift/include -L/usr/local/boost/lib
-L/usr/local/thrift/lib -lthrift -lthriftnb -levent client.cpp

这只是一个比较简单的例子,服务器是用的是TSimpleServer,是阻塞单线程的服务器,一般在线上跑的不会用到这个服务器,因此后续篇会介绍如何使用TNonblockingServer编写非阻塞多线程的服务器。

抱歉!评论已关闭.