zoukankan      html  css  js  c++  java
  • [zz]使用thrift做c++,java和python的相互调用

    [zz]使用thrift做c++,java和python的相互调用 - zaleilynn - 博客园

    [zz]使用thrift做c++,java和python的相互调用



    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代码  收藏代码

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


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

        thrift -r --gen cpp acsuser.thrift  
        thrift -r --gen java acsuser.thrift  
        thrift -r --gen py acsuser.thrift  


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

    3.生成C++服务端代码
    Shell代码  收藏代码

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


    修改UserServer.cpp
    C++代码  收藏代码

        #include "UserService.h" 
        #include <config.h> 
        //#include <protocol/TBinaryProtocol.h> 
        #include <protocol/TCompactProtocol.h> 
        #include <server/TSimpleServer.h> 
        #include <transport/TServerSocket.h> 
        #include <transport/TBufferTransports.h> 
        #include <concurrency/ThreadManager.h> 
        #include <concurrency/PosixThreadFactory.h> 
        #include <server/TThreadPoolServer.h> 
        #include <server/TThreadedServer.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 boost::shared_ptr; 
         
        class UserServiceHandler : virtual public UserServiceIf { 
         public: 
          UserServiceHandler() { 
            // Your initialization goes here 
          } 
         
          void add(const User& u) { 
            // Your implementation goes here 
            printf("uid=%s uname=%s usex=%d uage=%d\n", u.uid.c_str(), u.uname.c_str(), u.usex, u.uage); 
          } 
         
          void get(User& _return, const std::string& uid) { 
            // Your implementation goes here 
            _return.uid = "leo1"; 
            _return.uname = "yueyue"; 
            _return.usex = 1; 
            _return.uage = 3; 
            printf("uid=%s uname=%s usex=%d uage=%d\n", _return.uid.c_str(), _return.uname.c_str(), _return.usex, _return.uage); 
          } 
         
        }; 
         
        int main(int argc, char **argv) { 
          shared_ptr<UserServiceHandler> handler(new UserServiceHandler()); 
          shared_ptr<TProcessor> processor(new UserServiceProcessor(handler)); 
          shared_ptr<TProtocolFactory> protocolFactory(new TCompactProtocolFactory()); 
          shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory()); 
          shared_ptr<TServerTransport> serverTransport(new TServerSocket(9090)); 
         
          shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(10); 
          shared_ptr<PosixThreadFactory> threadFactory = shared_ptr<PosixThreadFactory>(new PosixThreadFactory()); 
          threadManager->threadFactory(threadFactory); 
          threadManager->start(); 
          printf("start user server...\n"); 
         
          TThreadPoolServer server(processor, serverTransport, transportFactory, protocolFactory, threadManager); 
          server.serve(); 
          return 0; 
        } 


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

    4.生成C++的client文件UserClient.cpp
    C++代码  收藏代码

        #include "UserService.h" 
        #include <config.h> 
        #include <transport/TSocket.h> 
        #include <transport/TBufferTransports.h> 
        #include <protocol/TCompactProtocol.h> 
         
        using namespace apache::thrift; 
        using namespace apache::thrift::protocol; 
        using namespace apache::thrift::transport; 
         
        using boost::shared_ptr; 
         
        int main(int argc, char **argv) { 
                boost::shared_ptr<TSocket> socket(new TSocket("localhost", 9090)); 
                boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket)); 
                boost::shared_ptr<TProtocol> protocol(new TCompactProtocol(transport)); 
         
                transport->open(); 
         
                User u; 
                u.uid = "leo"; 
                u.uname = "yueyue"; 
                u.usex = 1; 
                u.uage = 3; 
         
                UserServiceClient client(protocol); 
                client.add(u); 
         
                User u1; 
                client.get(u1,"lll"); 
         
                transport->close(); 
                printf("uid=%s uname=%s usex=%d uage=%d\n", u1.uid.c_str(), u1.uname.c_str(), u1.usex, u1.uage); 
                return 0; 
        } 



    5.生成Makefile
    Makefile代码  收藏代码

        BOOST_DIR = /usr/local/include/boost/ 
        THRIFT_DIR = /usr/local/include/thrift 
        LIB_DIR = /usr/local/lib 
        GEN_SRC = ./gen-cpp/acsuser_types.cpp ./gen-cpp/acsuser_constants.cpp ./gen-cpp/UserService.cpp 
        default: server client 
        server: UserServer.cpp 
                g++ -g -o UserServer -I${THRIFT_DIR} -I${BOOST_DIR}  -I./gen-cpp -L${LIB_DIR} -lthrift UserServer.cpp ${GEN_SRC} 
        client: UserClient.cpp 
                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} 
        clean: 
                $(RM) -r UserServer UserClient 



    6.启动c++ server
    Shell代码  收藏代码

        ./UserServer 


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

        ./UserClient 


    8.写java client文件UserClient.java
    Java代码  收藏代码

        import org.apache.thrift.TException; 
        import org.apache.thrift.protocol.TCompactProtocol; 
        import org.apache.thrift.protocol.TProtocol; 
        import org.apache.thrift.transport.TFramedTransport; 
        import org.apache.thrift.transport.TNonblockingSocket; 
        import org.apache.thrift.transport.TSocket; 
        import org.apache.thrift.transport.TTransport; 
        import org.apache.thrift.transport.TTransportException; 
         
        //import UserService.Client; 
         
        public class UserClient { 
            private void start() { 
                try { 
                    TTransport socket = new TSocket("localhost", 9090); 
                    //TTransport transport = new TFramedTransport(socket); 
                    TProtocol protocol = new TCompactProtocol(socket); 
         
                    UserService.Client client = new UserService.Client(protocol); 
                    socket.open(); 
                    System.out.println(client.get("lll")); 
         
                    User u = new User(); 
                    u.uid="leojava"; 
                    u.uname="yueyue"; 
                    u.usex=true; 
                    u.uage=3; 
                    client.add(u); 
                    socket.close(); 
         
                } catch (TTransportException e) { 
                    e.printStackTrace(); 
                } catch (TException e) { 
                    e.printStackTrace(); 
                } 
            } 
         
            public static void main(String[] args) { 
                UserClient c = new UserClient(); 
                c.start(); 
         
            } 
        } 


    编译和运行java client
    Shell代码  收藏代码

        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 
        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代码  收藏代码

        #!/usr/bin/env python 
        import sys 
        sys.path.append('./gen-py') 
        from acsuser import UserService 
        from acsuser.ttypes import * 
        from thrift import Thrift 
        from thrift.transport import TSocket 
        from thrift.transport import TTransport 
        from thrift.protocol import TCompactProtocol 
         
        # Make socket 
        transport = TSocket.TSocket('localhost', 9090) 
        # Buffering is critical. Raw sockets are very slow 
        transport = TTransport.TBufferedTransport(transport) 
        # Wrap in a protocol 
        protocol = TCompactProtocol.TCompactProtocol(transport) 
        # Create a client to use the protocol encoder 
        client = UserService.Client(protocol) 
        # Connect! 
        transport.open() 
        # Call Server services   
        u = client.get('lll') 
        print 'uid=%s uname=%s usex=%d u.uage=%d' %(u.uid,u.uname,u.usex,u.uage) 
         
        u1 = User() 
        u1.uid='leo' 
        u1.uname='yueyue' 
        u1.usex=1 
        u1.uage=3 
        client.add(u1) 


    执行python client代码
    Shell代码  收藏代码

        chmod 777 PythonClient.py 
        ./PythonClient.py 

        sample.tar.gz (2.1 KB)
        描述: 源文件
        下载次数: 22

    分类: thrift
  • 相关阅读:
    地址null发布新的JS游戏《吞食蛇永恒激情版》
    iteratornullHDU4302(map的用法)
    对象类亮剑.NET的系列文章之.NET详解(开端)
    视频连接【视频】Arduino 以太网插板介绍
    选中条目android spinner的使用
    进口问题限制进口肯定解决不了煤炭业问题
    方向搜索hdu 1180 诡异的楼梯 楼梯可以变方向的搜索题
    添加设置Android编程心得为TextView添加各种样式
    字符字符串字符串笔试面试题
    设置部门公用流程,上级领导审批,设置注意事项
  • 原文地址:https://www.cnblogs.com/lexus/p/2920010.html
Copyright © 2011-2022 走看看