首先假设你已经安装好thrift,我用的是CentOS7.2
C++
[root@thrift gen-cpp]# thrift --version
Thrift version 1.0.0-dev
[root@thrift cal]# vi cal.thrift
struct nums {
1: i32 i1;
2: i32 i2;
}
service sumservice {
void sum(1: nums n)
}
然后用thrift产生cpp的header及source档案
[root@thrift cal]# thrift --gen cpp cal.thrift
可以看见产生了gen-cpp文件夹,进入gen-cpp文件夹,看见以下几个产生出来的文件。
其中3组.h及.cpp文件:cal_constants.*,cal_types.*,sumservice.*,共6个文件thrift已经完全写好。
cal_constants.* 及 cal_types.* 的命名方式是基于cal.thrift档案名称的
sumservice.* 的命名方式cal.thrift档案里面所有的service的名称的
sumservice.*是server side交易资料的implementation
产生出来的3组.h及.cpp合共全部6个文件一般无需自行更改
其中3组.h及.cpp文件:cal_constants.*,cal_types.*,sumservice.*,共6个文件thrift已经完全写好。
cal_constants.* 及 cal_types.* 的命名方式是基于cal.thrift档案名称的
sumservice.* 的命名方式cal.thrift档案里面所有的service的名称的
sumservice.*是server side交易资料的implementation
产生出来的3组.h及.cpp合共全部6个文件一般无需自行更改
[root@thrift sum]# ls && cd gen-cpp/ && ls
cal.thrift gen-cpp
cal_constants.cpp cal_types.cpp sumservice.cpp sumservice_server.skeleton.cpp
cal_constants.h cal_types.h sumservice.h
留意sumservice.*里面的几个class名字及顺序
If, IfFactory, IfSingletonFactory, Null:If
args__isset, args, pargs, result, presult
Client:If, Processor:TDispatchProcessor, ProcessorFactory:TPorcessorFactory
Multiface:If, ConcurrentClient : If,
cal.thrift gen-cpp
cal_constants.cpp cal_types.cpp sumservice.cpp sumservice_server.skeleton.cpp
cal_constants.h cal_types.h sumservice.h
留意sumservice.*里面的几个class名字及顺序
If, IfFactory, IfSingletonFactory, Null:If
args__isset, args, pargs, result, presult
Client:If, Processor:TDispatchProcessor, ProcessorFactory:TPorcessorFactory
Multiface:If, ConcurrentClient : If,
唯一需要自行更改的是sumservice_server.skeleton.cpp, 这是Handler:If的
原本这个sumservice的预设implementation是把function名字打印出来
[root@thrift gen-cpp]# vi sumservice_server.skeleton.cpp
[root@thrift gen-cpp]# vi sumservice_server.skeleton.cpp
class sumserviceHandler : virtual public sumserviceIf {
public:
sumserviceHandler() {
// Your initialization goes here
}
void sum(const nums& n) {
// Your implementation goes here
printf("sum\n");
}
};
其中的main function大意是这样的,主要有关联的是Handler>TProcessor>TSimpleServer,而ServerTransport, TransportFactory及ProtocolFactory是配角。
int main() {
TSimpleServer server(TProcessor(sumserviceHandler()));
server.server();
};
由于每次运行都会把这歌现有的skeleton覆盖掉,所以现在干脆直接改名以免后顾之忧,改名以后列出的档案也比较工整
[root@thrift gen-cpp]# mv sumservice_server.skeleton.cpp server.cpp && ls
cal_constants.cpp cal_types.cpp client.cpp sumservice.cpp
cal_constants.h cal_types.h server.cpp sumservice.h
其中的main function大意是这样的,主要有关联的是Handler>TProcessor>TSimpleServer,而ServerTransport, TransportFactory及ProtocolFactory是配角。
int main() {
TSimpleServer server(TProcessor(sumserviceHandler()));
server.server();
};
由于每次运行都会把这歌现有的skeleton覆盖掉,所以现在干脆直接改名以免后顾之忧,改名以后列出的档案也比较工整
[root@thrift gen-cpp]# mv sumservice_server.skeleton.cpp server.cpp && ls
cal_constants.cpp cal_types.cpp client.cpp sumservice.cpp
cal_constants.h cal_types.h server.cpp sumservice.h
我们把server.cpp其中的两个方法改成以下有意义的内容,值得注意的是这两个方法都是放在一个由sumserviceIf界面虚疑继承的
[root@thrift gen-cpp]# vi server.cpp
class sumserviceHandler : virtual public sumserviceIf {
class sumserviceHandler : virtual public sumserviceIf {
sumserviceHandler() {
printf("server created \n");
}
void sum(const nums& n) {
printf("sum: %d + %d = %d \n", n.i1, n.i2, n.i1 + n.i2);
}
}
}
用g++编译server程序 其中server档案需要参考types, constants 及service档案,留意最后要加上-lthrift
[root@thrift gen-cpp]# g++ -o server server.cpp sumservice.cpp cal_types.cpp cal_constants.cpp -lthrift
可以试试把server程序跑起来,并且看见sumserviceHandler的建构子被呼叫了
[root@thrift gen-cpp]# ls
cal_constants.cpp cal_types.cpp server sumservice.h
cal_constants.h cal_types.h sumservice.cpp server.cpp
[root@thrift gen-cpp]# ./server
server created
^C
server created
^C
下一步要建立client代码去跟server程序沟通
首先要从sumservice.h找出你等下准备要继承的client class, grep Client一下会发现名有两个classes sumserviceClient 及 sumserviceConcurrentClient
[root@thrift gen-cpp]# grep Client sumservice.h
#include <thrift/async/TConcurrentClientSyncInfo.h>
class sumserviceClient : virtual public sumserviceIf {
sumserviceClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
sumserviceClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
class sumserviceConcurrentClient : virtual public sumserviceIf {
sumserviceConcurrentClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
sumserviceConcurrentClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
::apache::thrift::async::TConcurrentClientSyncInfo sync_;
client跟server的基本代码结构非常类似,所以直接考出来修改
首先要从sumservice.h找出你等下准备要继承的client class, grep Client一下会发现名有两个classes sumserviceClient 及 sumserviceConcurrentClient
[root@thrift gen-cpp]# grep Client sumservice.h
#include <thrift/async/TConcurrentClientSyncInfo.h>
class sumserviceClient : virtual public sumserviceIf {
sumserviceClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
sumserviceClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
class sumserviceConcurrentClient : virtual public sumserviceIf {
sumserviceConcurrentClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
sumserviceConcurrentClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
::apache::thrift::async::TConcurrentClientSyncInfo sync_;
client跟server的基本代码结构非常类似,所以直接考出来修改
[root@thrift gen-cpp]# cp server.cpp client.cpp && vi client.cpp
顶头加入TSocket.h并把main方法改成以下
#include <thrift/transport/TSocket.h>
int main(int argc, char **argv) {
shared_ptr<TSocket> socket(new TSocket("localhost", 9090));
shared_ptr<TTransport> transport(new TBufferedTransport(socket));
shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
transport->open();
// client code starts here
nums n;
n.i1 = 1;
n.i2 = 2;
sumserviceClient(protocol).sum(n);
// client code ends here
transport->close();
return 0;
}
client.cpp以下几句只跟server有关却跟client无关,正在写client code的我们为求简洁把他们移除掉。不怕,万一忘记移除,client程序还是可以编译跑起来的。
client.cpp中你会看见原本server的TTransportFactory及TProtocolFactory,如果把它们的Factory去掉就会变成client的要员
client.cpp整个就是这样
[root@thrift gen-cpp]# ./server &
[1] 22189
[root@thrift gen-cpp]# server created
./client
sum: 1 + 2 = 3
[root@thrift gen-cpp]# pkill server
做个最原始的makefile,可以看到server跟client档案的dependency
[root@thrift gen-cpp]# vi makefile
.PHONY: all
all: server client
server: cal_constants.cpp cal_types.cpp sumservice.cpp cal_constants.h cal_types.h server.cpp sumservice.h
g++ -std=c++11 -o server cal_constants.cpp cal_types.cpp sumservice.cpp server.cpp -lthrift
client: cal_constants.cpp cal_types.cpp client.cpp sumservice.cpp cal_constants.h cal_types.h server.cpp sumservice.h
g++ -std=c++11 -o client cal_constants.cpp cal_types.cpp sumservice.cpp client.cpp -lthrift
Python
假设你不用C++而要使用Python,用thrift产生cpp的header及source档案
[root@thrift sum]# thrift --gen py cal.thrift && ls && ls ./gen-py/ && ls ./gen-py/cal
cal.thrift gen-cpp gen-py
cal __init__.py
constants.py __init__.py sumservice.py sumservice-remote ttypes.py
可以看到thrift并不会把server代码skeleton产生给你,于是你需要在thrift档案同一目录下,建立以下的server.py,值得注意的是里面的CalHandler这个类并没有使用继承,只要是任何一个有写好sum(self,n)的类就可以送给sumservice.Processor()去被呼叫。留意,sumservice.py已经由thrift写好里面传送的代码,不用自己修改的。
[root@thrift sum]# vi server.py
参考./gen-py/sum/ttypes.py,可以看见nums已经写好了建构子,与c++的POD struct不同
class nums(object):
def __init__(self, i1=None, i2=None,):
self.i1=i1
self.i2=i2
[root@thrift sum]# vi client.py
#!/usr/bin/env python
Java
must use "127.0.0.1" instead of "localhost" in server.py and JavaClient.java
JavaClient.java
[ricky@thrift2 cal]$ thrift --gen java cal.thrift && ls gen-java
nums.java sumservice.java
[ricky@thrift1 gen-java]$ pwd
/home/ricky/dev/Thrift/cal/gen-java
#include <thrift/transport/TSocket.h>
int main(int argc, char **argv) {
shared_ptr<TSocket> socket(new TSocket("localhost", 9090));
shared_ptr<TTransport> transport(new TBufferedTransport(socket));
shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
transport->open();
// client code starts here
nums n;
n.i1 = 1;
n.i2 = 2;
sumserviceClient(protocol).sum(n);
// client code ends here
transport->close();
return 0;
}
client.cpp以下几句只跟server有关却跟client无关,正在写client code的我们为求简洁把他们移除掉。不怕,万一忘记移除,client程序还是可以编译跑起来的。
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
using namespace ::apache::thrift::server;
class sumserviceHandler
shared_ptr<sumserviceHandler> handler(new sumserviceHandler());
shared_ptr<TProcessor> processor(new sumserviceProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
shared_ptr<sumserviceHandler> handler(new sumserviceHandler());
shared_ptr<TProcessor> processor(new sumserviceProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
client.cpp中你会看见原本server的TTransportFactory及TProtocolFactory,如果把它们的Factory去掉就会变成client的要员
- boost::shared_ptr<TSocket> socket(new TSocket("localhost", 9090));
- boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
- boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
#include "sumservice.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TBufferTransports.h>
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using boost::shared_ptr;
#include <thrift/transport/TSocket.h>
int main(int argc, char **argv) {
shared_ptr<TSocket> socket(new TSocket("localhost", 9090));
shared_ptr<TTransport> transport(new TBufferedTransport(socket));
shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
transport->open();
// client code starts here
nums n;
n.i1 = 1;
n.i2 = 2;
sumserviceClient(protocol).sum(n);
// client code ends here
transport->close();
return 0;
}
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TBufferTransports.h>
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using boost::shared_ptr;
#include <thrift/transport/TSocket.h>
int main(int argc, char **argv) {
shared_ptr<TSocket> socket(new TSocket("localhost", 9090));
shared_ptr<TTransport> transport(new TBufferedTransport(socket));
shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
transport->open();
// client code starts here
nums n;
n.i1 = 1;
n.i2 = 2;
sumserviceClient(protocol).sum(n);
// client code ends here
transport->close();
return 0;
}
可以编译了
[root@thrift gen-cpp]# g++ -o client client.cpp sumservice.cpp cal_types.cpp cal_constants.cpp -lthrift
如果看见這个问题不要紧
[ricky@thrift1 gen-cpp]$ ./server
./server: error while loading shared libraries: libthrift-1.0.0-dev.so: cannot open shared object file: No such file or directory
可以跑了!背景跑server,前景跑client
如果看见這个问题不要紧
[ricky@thrift1 gen-cpp]$ ./server
./server: error while loading shared libraries: libthrift-1.0.0-dev.so: cannot open shared object file: No such file or directory
再跑一次就可以
$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
$ export LD_LIBRARY_PATH
$ ./server
可以跑了!背景跑server,前景跑client
[1] 22189
[root@thrift gen-cpp]# server created
./client
sum: 1 + 2 = 3
[root@thrift gen-cpp]# pkill server
做个最原始的makefile,可以看到server跟client档案的dependency
[root@thrift gen-cpp]# vi makefile
all: server client
server: cal_constants.cpp cal_types.cpp sumservice.cpp cal_constants.h cal_types.h server.cpp sumservice.h
g++ -std=c++11 -o server cal_constants.cpp cal_types.cpp sumservice.cpp server.cpp -lthrift
client: cal_constants.cpp cal_types.cpp client.cpp sumservice.cpp cal_constants.h cal_types.h server.cpp sumservice.h
g++ -std=c++11 -o client cal_constants.cpp cal_types.cpp sumservice.cpp client.cpp -lthrift
Python
假设你不用C++而要使用Python,用thrift产生cpp的header及source档案
[root@thrift sum]# thrift --gen py cal.thrift && ls && ls ./gen-py/ && ls ./gen-py/cal
cal.thrift gen-cpp gen-py
cal __init__.py
constants.py __init__.py sumservice.py sumservice-remote ttypes.py
[root@thrift sum]# vi server.py
#!/usr/bin/env python
import socket
import sys
sys.path.append('./gen-py')
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
from cal import sumservice
from cal.ttypes import *
class CalHandler :
def
sum(self, n) :
print(n.i1 + n.i2)
handler = CalHandler()
processor =
sumservice.Processor(handler)
transport =
TSocket.TServerSocket("127.0.0.1", 9090)
tfactory =
TTransport.TBufferedTransportFactory()
pfactory =
TBinaryProtocol.TBinaryProtocolFactory()
server =
TServer.TSimpleServer(processor, transport, tfactory, pfactory)
server.serve()
参考./gen-py/sum/ttypes.py,可以看见nums已经写好了建构子,与c++的POD struct不同
class nums(object):
def __init__(self, i1=None, i2=None,):
self.i1=i1
self.i2=i2
[root@thrift sum]# vi client.py
#!/usr/bin/env python
import sys
sys.path.append('./gen-py')
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from cal import sumservice
from cal.ttypes import *
try:
transport = TSocket.TSocket('127.0.0.1', 9090)
transport =
TTransport.TBufferedTransport(transport)
protocol =
TBinaryProtocol.TBinaryProtocol(transport)
client = sumservice.Client(protocol)
transport.open()
client.sum(nums(1,2)) # call constructor of nums()
class from ttypes.py
transport.close()
except Thrift.TException as ex:
print ("%s" % (ex.message))
Java
must use "127.0.0.1" instead of "localhost" in server.py and JavaClient.java
JavaClient.java
import
org.apache.thrift.TException;
import
org.apache.thrift.transport.TSSLTransportFactory;
import
org.apache.thrift.transport.TTransport;
import
org.apache.thrift.transport.TSocket;
import
org.apache.thrift.transport.TSSLTransportFactory.TSSLTransportParameters;
import
org.apache.thrift.protocol.TBinaryProtocol;
import
org.apache.thrift.protocol.TProtocol;
public class JavaClient {
public static void main(String[] args) {
try
{
TTransport transport;
transport = new TSocket("127.0.0.1", 9090);
transport.open();
TProtocol protocol = new TBinaryProtocol(transport);
sumservice.Client client = new sumservice.Client(protocol);
client.sum(new nums(1, 6));
System.out.println("done");
transport.close();
}
catch
(TException x) {
x.printStackTrace();
}
}
}
[ricky@thrift2 cal]$ thrift --gen java cal.thrift && ls gen-java
nums.java sumservice.java
[ricky@thrift1 gen-java]$ pwd
/home/ricky/dev/Thrift/cal/gen-java
cp /path/to/thrift/lib/java/build/lib/*.jar ./lib/
cp /path/to/thrift/lib/java/build/libthrift-1.0.0.jar ./lib/
[ricky@thrift2 gen-java]$ javac -cp ".:./lib/*" JavaClient.java && java -cp ".:./lib/*" JavaClientcp /path/to/thrift/lib/java/build/libthrift-1.0.0.jar ./lib/
沒有留言:
張貼留言