python mobile-hi.codemao.cn_使用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),

}

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

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

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

修改UserServer.cpp

C++代码

#include "UserService.h"

#include 

//#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

usingnamespace::apache::thrift;

usingnamespace::apache::thrift::protocol;

usingnamespace::apache::thrift::transport;

usingnamespace::apache::thrift::server;

usingnamespace::apache::thrift::concurrency;

usingboost::shared_ptr;

classUserServiceHandler :virtualpublicUserServiceIf {

public:

UserServiceHandler() {

// Your initialization goes here

}

voidadd(constUser& 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);

}

voidget(User& _return,conststd::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);

}

};

intmain(intargc,char**argv) {

shared_ptr handler(newUserServiceHandler());

shared_ptr processor(newUserServiceProcessor(handler));

shared_ptr protocolFactory(newTCompactProtocolFactory());

shared_ptr transportFactory(newTBufferedTransportFactory());

shared_ptr serverTransport(newTServerSocket(9090));

shared_ptr threadManager = ThreadManager::newSimpleThreadManager(10);

shared_ptr threadFactory = shared_ptr(newPosixThreadFactory());

threadManager->threadFactory(threadFactory);

threadManager->start();

printf("start user server...\n");

TThreadPoolServer server(processor, serverTransport, transportFactory, protocolFactory, threadManager);

server.serve();

return0;

}

#include "UserService.h"

#include

//#include

#include

#include

#include

#include

#include

#include

#include

#include

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 handler(new UserServiceHandler());

shared_ptr processor(new UserServiceProcessor(handler));

shared_ptr protocolFactory(new TCompactProtocolFactory());

shared_ptr transportFactory(new TBufferedTransportFactory());

shared_ptr serverTransport(new TServerSocket(9090));

shared_ptr threadManager = ThreadManager::newSimpleThreadManager(10);

shared_ptr threadFactory = shared_ptr(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

另外这个是Blocking的多线程服务器

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

C++代码

#include "UserService.h"

#include 

#include 

#include 

#include 

usingnamespaceapache::thrift;

usingnamespaceapache::thrift::protocol;

usingnamespaceapache::thrift::transport;

usingboost::shared_ptr;

intmain(intargc,char**argv) {

boost::shared_ptr socket(newTSocket("localhost", 9090));

boost::shared_ptr transport(newTBufferedTransport(socket));

boost::shared_ptr protocol(newTCompactProtocol(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);

return0;

}

#include "UserService.h"

#include

#include

#include

#include

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 socket(new TSocket("localhost", 9090));

boost::shared_ptr transport(new TBufferedTransport(socket));

boost::shared_ptr 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

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

./UserServer

7.测试c++ client

Shell代码

./UserClient

./UserClient

8.写java client文件UserClient.java

Java代码

importorg.apache.thrift.TException;

importorg.apache.thrift.protocol.TCompactProtocol;

importorg.apache.thrift.protocol.TProtocol;

importorg.apache.thrift.transport.TFramedTransport;

importorg.apache.thrift.transport.TNonblockingSocket;

importorg.apache.thrift.transport.TSocket;

importorg.apache.thrift.transport.TTransport;

importorg.apache.thrift.transport.TTransportException;

//import UserService.Client;

publicclassUserClient {

privatevoidstart() {

try{

TTransport socket =newTSocket("localhost",9090);

//TTransport transport = new TFramedTransport(socket);

TProtocol protocol =newTCompactProtocol(socket);

UserService.Client client =newUserService.Client(protocol);

socket.open();

System.out.println(client.get("lll"));

User u =newUser();

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();

}

}

publicstaticvoidmain(String[] args) {

UserClient c =newUserClient();

c.start();

}

}

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

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

importsys

sys.path.append('./gen-py')

fromacsuserimportUserService

fromacsuser.ttypesimport*

fromthriftimportThrift

fromthrift.transportimportTSocket

fromthrift.transportimportTTransport

fromthrift.protocolimportTCompactProtocol

# 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)

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

chmod777PythonClient.py

./PythonClient.py

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值