zoukankan      html  css  js  c++  java
  • 使用thrift做c++,java和python的相互调用 jinghong ITeye技术网站

    使用thrift做c++,java和python的相互调用 - jinghong - ITeye技术网站

    linux上安装thrift见
    http://jinghong.iteye.com/blog/1102535
    thrift做为跨语言调用的方案有高效,支持语言较多,成熟等优点;代码侵入较强是其弱点。
    下面记录以C++做服务器,C++,java和python做客户端的示例,这个和本人现在工作环境吻合,使用多线程长连接的socket来建立高效分布式系统的跨语言调用平台。
    遗憾的是目前版本(0.7.0)的C语言还不支持Compact协议,导致在现在的环境中nginx c module调用thrift要使用binary协议。thrift开发团队似乎对C语言不太感冒。
    1.定义idl文件acsuser.thrift
    Idl代码  收藏代码
    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代码框架
    Shell代码  收藏代码
    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++服务端代码
    Shell代码  收藏代码
    1. cp gen-cpp/UserService_server.skeleton.cpp UserServer.cpp  

    修改UserServer.cpp
    C++代码  收藏代码
    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
    C++代码  收藏代码
    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
    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
    Shell代码  收藏代码
    1. ./UserServer  

    7.测试c++ client
    Shell代码  收藏代码
    1. ./UserClient  

    8.写java client文件UserClient.java
    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
    Shell代码  收藏代码
    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
    Python代码  收藏代码
    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代码
    Shell代码  收藏代码
    1. chmod 777 PythonClient.py  
    2. ./PythonClient.py  
  • 相关阅读:
    2
    vue学习03
    vue学习02
    2
    vue学习01
    pycharm中安装vue
    git
    form
    ajax
    中间件
  • 原文地址:https://www.cnblogs.com/lexus/p/2870632.html
Copyright © 2011-2022 走看看