使用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代码

  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. }  
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代码

  1. thrift -r --gen cpp acsuser.thrift    
  2. thrift -r --gen java acsuser.thrift    
  3. thrift -r --gen py acsuser.thrift   
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代码

  1. cp gen-cpp/UserService_server.skeleton.cpp UserServer.cpp  
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. }  
#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++代码

  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. }  
#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代码

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

  1. ./UserServer  
./UserServer

7.测试c++ client

Shell代码

  1. ./UserClient  
./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. }  
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代码

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

  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)  
#!/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代码

  1. chmod 777 PythonClient.py   
  2. ./PythonClient.py  
时间: 2024-10-28 22:35:38

使用thrift做c++,java和python的相互调用的相关文章

JAVA与.NET的相互调用通过Web服务实现相互调用

JAVA与.NET是现今世界竞争激烈的两大开发媒体,两者语言有很多相似的地方.而在很多大型的开发项目里面,往往需要使用两种语言进行集成开发.而很多的开发人员都会偏向于其中一种语言,在使用集成开发的时候对另一种语言感觉到畏惧.在这里在下向各位介绍一下,JAVA与.NET相互调用的例子.下面的介绍主要包括三方面:一是通过常用Web服务进行相互调用,二是使用TCP/IP套接字进行相互调用,三是使用Remote实现远程对象相互调用. 在这章里面先为大家介绍一下最简单,最常用的Web服务相互调用方式.首先

JAVA与.NET的相互调用——通过Web服务实现相互调用

JAVA与.NET是现今世界竞争激烈的两大开发媒体,两者语言有很多相似的地方.而在很多大型的开发项目里面,往往需要使用两种语言进行集成开发.而很多的开发人员都会偏向于其中一种语言,在使用集成开发的时候对另一种语言感觉到畏惧.在这里在下向各位介绍一下,JAVA与.NET相互调用的例子.下面的介绍主要包括三方面:一是通过常用Web服务进行相互调用,二是使用TCP/IP套接字进行相互调用,三是使用Remote实现远程对象相互调用. 在这章里面先为大家介绍一下最简单,最常用的Web服务相互调用方式.首先

JAVA与.NET的相互调用——通过Web服务实现“.NET研究”相互调用

JAVA与.NET是现今世界竞争激烈的两大开发媒体,两者语言有很多相似的地方.而在很多大型的开发项目里面,往往需要使用两种语言进行集成开发.而很多的开发人员都会偏向于其中一种语言,在使用集成开发的时候对另一种语言感觉到畏惧.在这里在下向各位介绍一下,JAVA与.NET相互调用的例子.下面的介绍主要包括三方面:一是通过常用Web服务进行相互调用,二是使用TCP/IP套接字进行相互调用,三是使用Remote实现远程对象相互调用. 在这章里面先为大家介绍一下最简单,最常用的Web服务相互调用方式.首先

JAVA与.NET的相互调用——TCP/IP相互调用基本架构

TCP/IP套接字的概念 TCP/IP(传输控制协议/网际协议)是网络互连的通信协议,通过它可以实现各种异构网络或异种机之间的互联通信.TCP/IP是Transmission Control Protocol/Internet Protocol的简写,中文译名为传输控制协议/因特网互联协议,又叫网络通讯协议,这个协议是Internet最基本的协议.Internet国际互联网络的基础,简单地说,就是由网络层的IP协议和传输层的TCP协议组成的.TCP/IP 定义了电子设备(比如计算机)如何连入因特

JAVA与.NET的相互调用——TCP/IP相互调“.NET研究”用基本架构

TCP/IP套接字的概念 TCP/IP(传输控制协议/网际协议)是网络互连的通信协议,通过它可以实现各种异构网络或异种机之间的互联通信.TCP/IP是Transmission Control Protocol/Internet Protocol的简写,中文译名为传输控制协议/因特网互联协议,又叫网络通讯协议,这个协议是Internet最基本的协议.Internet国际互联网络的基础,简单地说,就是由网络层的IP协议和传输层的TCP协议组成的.TCP/IP 定义了电子设备(比如计算机)如何连入因特

一起谈.NET技术,JAVA与.NET的相互调用——通过Web服务实现相互调用

JAVA与.NET是现今世界竞争激烈的两大开发媒体,两者语言有很多相似的地方.而在很多大型的开发项目里面,往往需要使用两种语言进行集成开发.而很多的开发人员都会偏向于其中一种语言,在使用集成开发的时候对另一种语言感觉到畏惧.在这里在下向各位介绍一下,JAVA与.NET相互调用的例子.下面的介绍主要包括三方面:一是通过常用Web服务进行相互调用,二是使用TCP/IP套接字进行相互调用,三是使用Remote实现远程对象相互调用. 在这章里面先为大家介绍一下最简单,最常用的Web服务相互调用方式.首先

JAVA与.NET的相互调用利用JNBridge桥接模式实现远程通讯

分布式开发的历史 利用Remote方式调用远程对象实现服务器与客户端之间通讯是一种常用的网络开发方式,在.NET与JAVA开发当中,对Remote远程对象早已有着足够的支持(对Remote远程对象调用有兴趣的朋友欢迎参考一下利用远程对象实现分布式开发). 从2003年开始.NET当中就盛传着.NET Remoting远程对象调用的分布式开发,.NET Remoting主要用于管理跨应用程序域的同步和异步RPC 会话.在默认情况下,Remoting可以使用 HTTP 或 TCP 协议进行信息通讯,

“.NET研究”JAVA与.NET的相互调用——利用JNBridge桥接模式实现远程通讯

分布式开发的历史 利用Remote方式调用远程对象实现服务器与客户端之间通讯是一种常用的网络开发方式,在.NET与JAVA开发当中,对Remote远程对象早已有着足够的支持(对Remote远程对象调用有兴趣的朋友欢迎参考一下利用远程对象实现分布式开发). 从2003年开始.NET当中就盛传着.NET Remoting远程对象调用的分布式开发,.NET Remoting主要用于管理跨应用程序域的同步和异步RPC 会话.在默认情况下,Remoting可以使用 HTTP 或 TCP 协议进行信息通讯,

JAVA与.NET的相互调用——利用JNBridge桥接模式实现远程通讯

分布式开发的历史 利用Remote方式调用远程对象实现服务器与客户端之间通讯是一种常用的网络开发方式,在.NET与JAVA开发当中,对Remote远程对象早已有着足够的支持(对Remote远程对象调用有兴趣的朋友欢迎参考一下利用远程对象实现分布式开发). 从2003年开始.NET当中就盛传着.NET Remoting远程对象调用的分布式开发,.NET Remoting主要用于管理跨应用程序域的同步和异步RPC 会话.在默认情况下,Remoting可以使用 HTTP 或 TCP 协议进行信息通讯,