1、首先需要安装依赖的软件包 ,参考网址官方安装说明
sudo apt-get install automake bison flex g++ git libboost-all-dev libevent-dev libssl-dev libtool make pkg-config
2、创建一个目录,用git下载源码或者到网站下载最新的稳定版源码包下载地址
git clone https://github.com/apache/thrift.git
cd thrift
3、执行安装步骤,简化为 一下几部分,如果不是通过git下载的,则不需要执行bootstrap.sh,参考编译源码过程
./bootstrap.sh
./configure
make
sudo make install
4、进行测试,编写exchange.thrift文件,文件内容如下
#!/usr/local/bin/thrift --gen cpp
namespace cpp Test
namespace java com.thrift.test
service NucInfoExchange {
string execute(1:string instruction)
void push(1:string message)
}
5、生成C++和Java代码
thrift --gen cpp exchange.thrift
thrift --gen java exchange.thrift
这两行命令将会在当前目录下生成gen-cpp和gen-java两个目录,这两个目录里面就是生成的C++和java代码
6、首先进入gen-cpp目录,将生成的NucInfoExchange_server.skeleton.cpp拷贝为NucInfoExchange_server.cpp,并修改代码,执行如下命令
cd gen-cpp
cp NucInfoExchange_server.skeleton.cpp NucInfoExchange_server.cpp
gedit NucInfoExchange_server.cpp
由于我主要想测试ThreadPool模式,所以对代码进行了修改,主要是加入了Processor的克隆类,修改了main函数,代码如下
// This autogenerated skeleton file illustrates how to build a server.
// You should copy it to another filename to avoid overwriting it.
#include "NucInfoExchange.h"
#include <thrift/concurrency/PlatformThreadFactory.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/TToString.h>
#include <thrift/stdcxx.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/concurrency/ThreadManager.h>
#include <thrift/concurrency/PosixThreadFactory.h>
#include <thrift/server/TThreadPoolServer.h>
#include <thrift/server/TThreadedServer.h>
#include <iostream>
#include <stdexcept>
#include <sstream>
using namespace std;
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 Test;
class NucInfoExchangeHandler : virtual public NucInfoExchangeIf {
public:
NucInfoExchangeHandler() {
// Your initialization goes here
}
void execute(std::string& _return, const std::string& instruction) {
// Your implementation goes here
printf("execute\n");
}
void push(const std::string& message) {
// Your implementation goes here
printf("push\n");
}
};
class NucInfoExchangeCloneFactory : virtual public NucInfoExchangeIfFactory {
public:
virtual ~NucInfoExchangeCloneFactory() {}
virtual NucInfoExchangeIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo)
{
stdcxx::shared_ptr<TSocket> sock = stdcxx::dynamic_pointer_cast<TSocket>(connInfo.transport);
cout << "Incoming connection\n";
cout << "\tSocketInfo: " << sock->getSocketInfo() << "\n";
cout << "\tPeerHost: " << sock->getPeerHost() << "\n";
cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n";
cout << "\tPeerPort: " << sock->getPeerPort() << "\n";
return new NucInfoExchangeHandler;
}
virtual void releaseHandler( NucInfoExchangeIf* handler) {
delete handler;
}
};
int main(int argc, char **argv) {
/* int port = 9898;
::apache::thrift::stdcxx::shared_ptr<NucInfoExchangeHandler> handler(new NucInfoExchangeHandler());
::apache::thrift::stdcxx::shared_ptr<TProcessor> processor(new NucInfoExchangeProcessor(handler));
::apache::thrift::stdcxx::shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
::apache::thrift::stdcxx::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
::apache::thrift::stdcxx::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
*/
const int workerCount = 4;
::apache::thrift::stdcxx::shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(workerCount);
threadManager->threadFactory(stdcxx::make_shared<PosixThreadFactory>());
threadManager->start();
TThreadPoolServer server(
stdcxx::make_shared<NucInfoExchangeProcessorFactory>(stdcxx::make_shared<NucInfoExchangeCloneFactory>()),
stdcxx::make_shared<TServerSocket>(9898),
stdcxx::make_shared<TBufferedTransportFactory>(),
stdcxx::make_shared<TBinaryProtocolFactory>(),
threadManager);
server.serve();
return 0;
}
7、开始编译,编写Makefile文件如下
GEN_SRC := NucInfoExchange.cpp exchange_constants.cpp exchange_types.cpp
GEN_OBJ := $(patsubst %.cpp,%.o, $(GEN_SRC))
THRIFT_DIR := /usr/local/include/thrift
BOOST_DIR := /usr/include/boost
INC := -I$(THRIFT_DIR) -I$(BOOST_DIR)
.PHONY: all clean
all: NucInfoExchange_server
%.o: %.cpp
$(CXX) -Wall -O2 -DHAVE_INTTYPES_H -DHAVE_NETINET_IN_H $(INC) -c $< -o $@
NucInfoExchange_server: NucInfoExchange_server.o $(GEN_OBJ)
$(CXX) $^ -o $@ -L/usr/local/lib -lthrift
clean:
$(RM) *.o NucInfoExchange_server
执行make命令,编译没有问题,出现了怪异的链接错误如下
g++ -Wall -O2 -DHAVE_INTTYPES_H -DHAVE_NETINET_IN_H -I/usr/local/include/thrift -I/usr/include/boost -c NucInfoExchange_server.cpp -o NucInfoExchange_server.o
g++ -Wall -O2 -DHAVE_INTTYPES_H -DHAVE_NETINET_IN_H -I/usr/local/include/thrift -I/usr/include/boost -c NucInfoExchange.cpp -o NucInfoExchange.o
g++ -Wall -O2 -DHAVE_INTTYPES_H -DHAVE_NETINET_IN_H -I/usr/local/include/thrift -I/usr/include/boost -c exchange_constants.cpp -o exchange_constants.o
g++ -Wall -O2 -DHAVE_INTTYPES_H -DHAVE_NETINET_IN_H -I/usr/local/include/thrift -I/usr/include/boost -c exchange_types.cpp -o exchange_types.o
g++ NucInfoExchange_server.o NucInfoExchange.o exchange_constants.o exchange_types.o -o NucInfoExchange_server -L/usr/local/lib -lthrift
NucInfoExchange_server.o:在函数‘main’中:
NucInfoExchange_server.cpp:(.text.startup+0x1e9):对‘apache::thrift::server::TThreadPoolServer::TThreadPoolServer(boost::shared_ptr<apache::thrift::TProcessorFactory> const&, boost::shared_ptr<apache::thrift::transport::TServerTransport> const&, boost::shared_ptr<apache::thrift::transport::TTransportFactory> const&, boost::shared_ptr<apache::thrift::protocol::TProtocolFactory> const&, boost::shared_ptr<apache::thrift::concurrency::ThreadManager> const&)’未定义的引用
collect2: error: ld returned 1 exit status
Makefile:17: recipe for target 'NucInfoExchange_server' failed
make: *** [NucInfoExchange_server] Error 1
看错误是链接的时候找不到ThreadPoolServer类,不能啊,这个肯定有,难道是用git下载的版本太高了?删除了所有的thrift文件,在官网上又下载了最新的稳定版thrift-0.11.0.tar.gz ,解压编译后,继续编译这个例子,依然是同样的错误,折腾的都快精神崩溃了,又仔细看了看错误,为啥用的全都是boost::shared_ptr呢,印象中编译时候显示的是std=C++11 啊,灵机一动,赶紧修改Makefile文件如下
GEN_SRC := NucInfoExchange.cpp exchange_constants.cpp exchange_types.cpp
GEN_OBJ := $(patsubst %.cpp,%.o, $(GEN_SRC))
THRIFT_DIR := /usr/local/include/thrift
BOOST_DIR := /usr/include/boost
INC := -I$(THRIFT_DIR) -I$(BOOST_DIR)
.PHONY: all clean
all: NucInfoExchange_server
%.o: %.cpp
$(CXX) -Wall -std=c++11 -O2 -DHAVE_INTTYPES_H -DHAVE_NETINET_IN_H $(INC) -c $< -o $@
NucInfoExchange_server: NucInfoExchange_server.o $(GEN_OBJ)
$(CXX) $^ -o $@ -L/usr/local/lib -lthrift
clean:
$(RM) *.o NucInfoExchange_server
大家仔细看,编译时增加了一个 -std=c++11选项,赶紧运行make尝试一下,OK,成功了
8、在另外一台windows上写个java测试的客户端吧,测试代码如下
package com.thrift.test;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
public class TestThrift {
public static void main(String[] args) {
System.out.println("客户端启动....");
for(int i = 0; i < 100 ; i++){
TestThread ts = new TestThread();
Thread thread = new Thread(ts);
thread.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class TestThread implements Runnable{
public void run() {
TTransport transport = null;
try {
transport = new TSocket("192.168.1.105", 9898, 30000);
// 协议要和服务端一致
TProtocol protocol = new TBinaryProtocol(transport);
NucInfoExchange.Client client = new NucInfoExchange.Client(protocol);
transport.open();
String result = client.execute("哈哈!!!!");
System.out.println(result);
} catch (TTransportException e) {
e.printStackTrace();
} catch (TException e) {
e.printStackTrace();
} finally {
if (null != transport) {
transport.close();
}
}
}
}
9、终于大功告成了,折腾了大半天的时间,终于搞定了,baidu和bing都用了,没有找到任何线索,所以赶紧记录下来,免得日后忘记了,很不容易。希望也能帮到别人。