转自:http://blog.csdn.net/andy_yf/article/details/7487384

thrift做为跨语言调用的方案有高效,支持语言较多,成熟等优点;代码侵入较强是其弱点。 
下面记录以C++做服务器,C++,javapython做客户端的示例,这个和本人现在工作环境吻合,使用多线程长连接的socket来建立高效分布式系统的跨语言调用平台。遗憾的是目前版本(0.7.0)的C语言还不支持Compact协议,导致在现在的环境中nginx c module调用thrift要使用binary协议。thrift开发团队似乎对C语言不太感冒。

1.定义idl文件acsuser.thrift 

 struct User{
: string uid,
: string uname,
: bool usex,
: i16 uage,
}
service UserService{
void add(: User u),
User get(: 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 = ;
_return.uage = ;
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()); shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager();
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 ;
}

注意这段代码使用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", ));
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 = ;
u.uage = ; 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 ;
}

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", );
//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=;
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..jar:/usr/local/lib/log4j-1.2..jar:/usr/local/lib/commons-logging-1.1..jar:/usr/local/lib/slf4j-api-1.5..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', )
# 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=
u1.uage=
client.add(u1)

执行python client代码

 chmod  PythonClient.py
./PythonClient.py

利用thrift在c++、java和python之间相互调用的更多相关文章

  1. 《精通并发与Netty》学习笔记(07 - 基于Thrift实现Java与Python的RPC调用)

    上节我们介绍了基于Thrift实现java与java的RPC调用,本节我们基于Thrift实现Java与Python的RPC调用 首先,修改data.thirft文件,将命名空间由java改为py n ...

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

    分布式开发的历史 利用Remote方式调用远程对象实现服务器与客户端之间通讯是一种常用的网络开发方式,在.NET与JAVA开发当中,对Remote远程对象早已有着足够的支持(对Remote远程对象调用 ...

  3. java和C++之间的调用

    java和C++之间的调用其实和C差不多,只是有几点不一样 区别: 包名.类名.h 这个头文件必须有且必须在JNI目录里 后缀不需要修改 /* DO NOT EDIT THIS FILE - it i ...

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

    JAVA与.NET是现今世界竞争激烈的两大开发媒体,两者语言有很多相似的地方.而在很多大型的开发项目里面,往往需要使用两种语言进行集成开发.而很多的开发人员都会偏向于其中一种语言,在使用集成开发的时候 ...

  5. .Net 与 Java 的服务接口相互调用

    本文介绍.Net 与 Java 相互调用的例子.下面的介绍主要包括三方面:一是通过常用Web服务进行相互调用,二是使用TCP/IP套接字进行相互调用,三是使用Remote实现远程对象相互调用. 首先说 ...

  6. synchronized修饰的方法之间相互调用

    1:synchronized修饰的方法之间相互调用,执行结果为There hello  ..因为两个方法(main,hello)的synchronized形成了互斥锁.  所以当main方法执行完之后 ...

  7. Java-web-多个独立项目之间相互调用实践

    本篇文章只涉及到应用层面,没有涉及到什么底层原理之类的,我目前的实力还没有达到那个级别.如果是大神级别的人看到这篇文章,请跳过. 项目框架也已经是搭建好了的,springboot版本为1.5,数据库操 ...

  8. 两个Java项目之间相互调用

    转自:http://dysfzhoulong.iteye.com/blog/1008747 一个项目A另一个项目B:(项目A和项目B都是Java写的项目) 在A项目中怎么调用B项目中的类和方法 有两种 ...

  9. iframe父子页面之间相互调用元素和函数

    <!doctype html> <html> <head> <meta http-equiv="Content-Type" content ...

随机推荐

  1. 标C编程笔记day04 预处理、宏定义、条件编译、makefile、结构体使用

    预处理:也就是包括须要的头文件,用#include<标准头文件>或#include "自己定义的头文件" 宏定义,如:#define PI 3.1415926 查看用宏 ...

  2. 解决最新版的ADT没有NDK选项的问题

    最新版的ADT不显示NDK,解决方法有两种,第一种方法在线重装一下 这种方法有一个问题就是,google的东西我们经常不能访问,解决方法可以参考http://blog.csdn.net/shi_wei ...

  3. hud 1465、2049、2045 (递推)[含简单C(n,m) n!的写法]

    C - 不容易系列之一 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit  ...

  4. 博客系统-评论or评论树

    url配置 url(r'^commentTree/(?P<article_id>\d+)/',views.commentTree), url(r'^(?P<username>. ...

  5. IP数据报首部格式

    IP协议提供不可靠.无连接的数据报传送服务. 不可靠:尽力而为地传输,不保证IP数据报能成功到达目的地. 无连接:每一个数据报之间相互独立地进行路由选择,可不按发送顺序接收. IP首部格式例如以下: ...

  6. 【bzoj3620】似乎在梦中见过的样子

    枚举左端点,对于每个右端点处理出以右端点为结尾最大长度使得从左端点开始的前缀等于以右端点结束的后缀,即next数组 然后一直往前跳,直到长度小于子串长度的一半为止. #include<algor ...

  7. monggodb 复制集 集群 搭建

    https://docs.mongodb.com/manual/tutorial/enable-authentication/ Overview Enabling access control on ...

  8. aapt2 错误

    android.enableAapt2=false Error:Execution failed for task ':app:preDebugAndroidTestBuild'. > Conf ...

  9. sjtu oj 1201. SuperXOR

    Description Pangzi recently realized that bitwise XOR operation is just an addition without carries. ...

  10. codeforces 679e Bear and Bad Powers of 42

    传送门:http://codeforces.com/contest/679/problem/E 题目意思很清晰,给你一个序列,要求你完成以下三个操作: 1.输出A[i] 2.将[a,b]区间的所有数字 ...