设为首页 收藏本站
查看: 772|回复: 0

[经验分享] 使用thrift做c++,java和python的相互调用

[复制链接]

尚未签到

发表于 2017-5-6 06:02:22 | 显示全部楼层 |阅读模式
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

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

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++服务端代码

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

修改UserServer.cpp

#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

#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

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

./UserServer

7.测试c++ client

./UserClient

8.写java client文件UserClient.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

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

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

chmod 777 PythonClient.py
./PythonClient.py

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-373524-1-1.html 上篇帖子: Python 2.7 is required, which was not found in the registry 下篇帖子: Python核心编程之正则表达式-练习题解答
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表