码迷,mamicode.com
首页 > 编程语言 > 详细

利用thrift在c++、java和python之间相互调用

时间:2016-04-13 00:04:13      阅读:260      评论:0      收藏:0      [点我收藏+]

标签:

转自:http://blog.csdn.net/andy_yf/article/details/7487384

thrift做为跨语言调用的方案有高效,支持语言较多,成熟等优点;代码侵入较强是其弱点。 
下面记录以C++做服务器,C++,javapython做客户端的示例,这个和本人现在工作环境吻合,使用多线程长连接的socket来建立高效分布式系统的跨语言调用平台。遗憾的是目前版本(0.7.0)的C语言还不支持Compact协议,导致在现在的环境中nginx c module调用thrift要使用binary协议。thrift开发团队似乎对C语言不太感冒。 

1.定义idl文件acsuser.thrift 

 

 1 struct User{    
 2  1: string uid,    
 3  2: string uname,    
 4  3: bool usex,    
 5  4: i16 uage,    
 6 }    
 7 service UserService{    
 8  void add(1: User u),    
 9  User get(1: string uid),    
10 }    

 

2.生成c++,java和python代码框架 

1 thrift -r --gen cpp acsuser.thrift     
2 thrift -r --gen java acsuser.thrift     
3 thrift -r --gen py acsuser.thrift  

这时生成子目录gen-cpp,gen-java,gen-py 

3.生成C++服务端代码

cp gen-cpp/UserService_server.skeleton.cpp UserServer.cpp   

修改UserServer.cpp

 1 #include "UserService.h"    
 2 #include <config.h>    
 3 //#include <protocol/TBinaryProtocol.h>    
 4 #include <protocol/TCompactProtocol.h>    
 5 #include <server/TSimpleServer.h>    
 6 #include <transport/TServerSocket.h>    
 7 #include <transport/TBufferTransports.h>    
 8 #include <concurrency/ThreadManager.h>    
 9 #include <concurrency/PosixThreadFactory.h>    
10 #include <server/TThreadPoolServer.h>    
11 #include <server/TThreadedServer.h>    
12     
13 using namespace ::apache::thrift;    
14 using namespace ::apache::thrift::protocol;    
15 using namespace ::apache::thrift::transport;    
16 using namespace ::apache::thrift::server;    
17 using namespace ::apache::thrift::concurrency;    
18     
19 using boost::shared_ptr;    
20     
21 class UserServiceHandler : virtual public UserServiceIf {    
22  public:    
23   UserServiceHandler() {    
24     // Your initialization goes here    
25   }    
26     
27   void add(const User& u) {    
28     // Your implementation goes here    
29     printf("uid=%s uname=%s usex=%d uage=%d\n", u.uid.c_str(), u.uname.c_str(), u.usex, u.uage);    
30   }    
31     
32   void get(User& _return, const std::string& uid) {    
33     // Your implementation goes here    
34     _return.uid = "leo1";    
35     _return.uname = "yueyue";    
36     _return.usex = 1;    
37     _return.uage = 3;    
38     printf("uid=%s uname=%s usex=%d uage=%d\n", _return.uid.c_str(), _return.uname.c_str(), _return.usex, _return.uage);    
39   }    
40     
41 };    
42     
43 int main(int argc, char **argv) {    
44   shared_ptr<UserServiceHandler> handler(new UserServiceHandler());    
45   shared_ptr<TProcessor> processor(new UserServiceProcessor(handler));    
46   shared_ptr<TProtocolFactory> protocolFactory(new TCompactProtocolFactory());    
47   shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());    
48   shared_ptr<TServerTransport> serverTransport(new TServerSocket(9090));    
49     
50   shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(10);    
51   shared_ptr<PosixThreadFactory> threadFactory = shared_ptr<PosixThreadFactory>(new PosixThreadFactory());    
52   threadManager->threadFactory(threadFactory);    
53   threadManager->start();    
54   printf("start user server...\n");    
55     
56   TThreadPoolServer server(processor, serverTransport, transportFactory, protocolFactory, threadManager);    
57   server.serve();    
58   return 0;    
59 }    

注意这段代码使用TCompactProtocol,需要#include <config.h> 
另外这个是Blocking的多线程服务器

4.生成C++的client文件UserClient.cpp 

 1 #include "UserService.h"    
 2 #include <config.h>    
 3 #include <transport/TSocket.h>    
 4 #include <transport/TBufferTransports.h>    
 5 #include <protocol/TCompactProtocol.h>    
 6     
 7 using namespace apache::thrift;    
 8 using namespace apache::thrift::protocol;    
 9 using namespace apache::thrift::transport;    
10     
11 using boost::shared_ptr;    
12     
13 int main(int argc, char **argv) {    
14         boost::shared_ptr<TSocket> socket(new TSocket("localhost", 9090));    
15         boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));    
16         boost::shared_ptr<TProtocol> protocol(new TCompactProtocol(transport));    
17     
18         transport->open();    
19     
20         User u;    
21         u.uid = "leo";    
22         u.uname = "yueyue";    
23         u.usex = 1;    
24         u.uage = 3;    
25     
26         UserServiceClient client(protocol);    
27         client.add(u);    
28     
29         User u1;    
30         client.get(u1,"lll");    
31     
32         transport->close();    
33         printf("uid=%s uname=%s usex=%d uage=%d\n", u1.uid.c_str(), u1.uname.c_str(), u1.usex, u1.uage);    
34         return 0;    
35 }    

5.生成Makefile 

 

 1 BOOST_DIR = /usr/local/include/boost/    
 2 THRIFT_DIR = /usr/local/include/thrift    
 3 LIB_DIR = /usr/local/lib    
 4 GEN_SRC = ./gen-cpp/acsuser_types.cpp ./gen-cpp/acsuser_constants.cpp ./gen-cpp/UserService.cpp    
 5 default: server client    
 6 server: UserServer.cpp    
 7         g++ -g -o UserServer -I${THRIFT_DIR} -I${BOOST_DIR}  -I./gen-cpp -L${LIB_DIR} -lthrift UserServer.cpp ${GEN_SRC}    
 8 client: UserClient.cpp    
 9         g++ -g -o UserClient -lm -pthread -lz -lrt -lssl -I${THRIFT_DIR} -I${BOOST_DIR}  -I./gen-cpp -L${LIB_DIR} -lthrift UserClient.cpp ${GEN_SRC}    
10 clean:    
11         $(RM) -r UserServer UserClient    

 

6.启动c++ server 

 

1 ./UserServer

 

7.测试c++ client 

 

1 ./UserClient

 

8.写java client文件UserClient.java

 1 import org.apache.thrift.TException;    
 2 import org.apache.thrift.protocol.TCompactProtocol;    
 3 import org.apache.thrift.protocol.TProtocol;    
 4 import org.apache.thrift.transport.TFramedTransport;    
 5 import org.apache.thrift.transport.TNonblockingSocket;    
 6 import org.apache.thrift.transport.TSocket;    
 7 import org.apache.thrift.transport.TTransport;    
 8 import org.apache.thrift.transport.TTransportException;    
 9     
10 //import UserService.Client;    
11     
12 public class UserClient {    
13     private void start() {    
14         try {    
15             TTransport socket = new TSocket("localhost", 9090);    
16             //TTransport transport = new TFramedTransport(socket);    
17             TProtocol protocol = new TCompactProtocol(socket);    
18     
19             UserService.Client client = new UserService.Client(protocol);    
20             socket.open();    
21             System.out.println(client.get("lll"));    
22     
23             User u = new User();    
24             u.uid="leojava";    
25             u.uname="yueyue";    
26             u.usex=true;    
27             u.uage=3;    
28             client.add(u);    
29             socket.close();    
30     
31         } catch (TTransportException e) {    
32             e.printStackTrace();    
33         } catch (TException e) {    
34             e.printStackTrace();    
35         }    
36     }    
37     
38     public static void main(String[] args) {    
39         UserClient c = new UserClient();    
40         c.start();    
41     
42     }    
43 }    

编译和运行java client 

1 javac -classpath /usr/local/lib/libthrift-0.7.0.jar:/usr/local/lib/log4j-1.2.14.jar:/usr/local/lib/commons-logging-1.1.1.jar:/usr/local/lib/slf4j-api-1.5.8.jar UserClient.java ./gen-java/*.java    
2 java -classpath .:./gen-java:/usr/local/lib/libthrift-0.7.0.jar:/usr/local/lib/log4j-1.2.14.jar:/usr/local/lib/commons-logging-1.1.1.jar:/usr/local/lib/slf4j-api-1.5.8.jar:/usr/local/lib/slf4j-log4j12-1.5.8.jar UserClient   

9.写Python client文件PythonClient.py 

 1 #!/usr/bin/env python    
 2 import sys    
 3 sys.path.append(./gen-py)    
 4 from acsuser import UserService    
 5 from acsuser.ttypes import *    
 6 from thrift import Thrift    
 7 from thrift.transport import TSocket    
 8 from thrift.transport import TTransport    
 9 from thrift.protocol import TCompactProtocol    
10     
11 # Make socket    
12 transport = TSocket.TSocket(localhost, 9090)    
13 # Buffering is critical. Raw sockets are very slow    
14 transport = TTransport.TBufferedTransport(transport)    
15 # Wrap in a protocol    
16 protocol = TCompactProtocol.TCompactProtocol(transport)    
17 # Create a client to use the protocol encoder    
18 client = UserService.Client(protocol)    
19 # Connect!    
20 transport.open()    
21 # Call Server services      
22 u = client.get(lll)    
23 print uid=%s uname=%s usex=%d u.uage=%d %(u.uid,u.uname,u.usex,u.uage)    
24     
25 u1 = User()    
26 u1.uid=leo    
27 u1.uname=yueyue    
28 u1.usex=1    
29 u1.uage=3    
30 client.add(u1)    

执行python client代码 

1 chmod 777 PythonClient.py    
2 ./PythonClient.py  

 

利用thrift在c++、java和python之间相互调用

标签:

原文地址:http://www.cnblogs.com/lpxblog/p/5384891.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!