浙江省高等学校教师教育理论培训

微信搜索“毛凌志岗前心得”小程序

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[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
posted on 2013-02-21 09:44  lexus  阅读(379)  评论(0编辑  收藏  举报