转自: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. 线程特定数据TSD总结

    一线程的本质 二线程模型的引入 三线程特定数据 四关键函数说明 五刨根问底啥原理 六私有数据使用演示样例 七參考文档 一.线程的本质 Linux线程又称轻量进程(LWP),也就说线程本质是用进程之间共 ...

  2. 玩转Bash脚本:循环结构之while循环(转)

    转自:http://blog.csdn.net/guodongxiaren/article/details/43341769   总第8篇 本系列(玩转Bash脚本)更多文章,请访问:http://b ...

  3. Android手机输入法按键监听-dispatchKeyEvent

    近期在项目开发中遇到一个关于手机输入键盘的坑.特来记录下. 应用场景: 项目中有一个界面是用viewpaper加三个fragment写的,当中viewpaper被我屏蔽了左右滑动,上面有三个点击按钮, ...

  4. js前端3des加密 后台java解密

    import java.security.Key; import java.security.SecureRandom; import javax.crypto.Cipher; import java ...

  5. JAVA WEB学习笔记(二):Tomcat服务器的安装及配置

    一.Tomcat的下载及安装. 前往Tomcat官网下载安装包或者免安装压缩包.链接http://tomcat.apache.org/ 这里,我选择的是Tomcat8.0,而不是最新的Tomcat9. ...

  6. openwrt gstreamer实例学习笔记(六. gstreamer Pads及其功能)

    一:概述 如我们在Elements一章中看到的那样,Pads是element对外的接口.数据流从一个element的source pad到另一个element的sink pad.pads的功能(cap ...

  7. java-冒泡

    一.java冒泡排序 冒泡排序(Bubble Sort)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要 ...

  8. RubyMine安装、破解

    经常安装东西,这是我安装过最快的ide破解版. 下载地址: http://www.jetbrains.com/ruby/download/index.html 破解序列号: name: rubymin ...

  9. 20170218-取值Domain

    1.通过视图DD07V, 例子:取SD 凭证类别的DOMAIN(VBTYP)DATA: LT_DD07V TYPE TABLE OF DD07V.SELECT * INTO T_DD07V FROM ...

  10. (24) java web的struts2框架的使用-action参数自动封装与类型转换

    structs可以对参数进行自动封装,做法也很简单. 一,action参数自动封装: 1,可以直接在action类中,声明public的属性,接受参数. 2,属性也是是private,如果是priva ...