thrift应用举例(c/c++作为服务端、java作为客户端)
来源:互联网 发布:超高速网络 编辑:程序博客网 时间:2024/05/18 03:11
转自:http://dengqsintyt.iteye.com/blog/2005307
最近做的一个项目,后端服务是c++写的,因所有参与这个项目的同事除了me之外,他们都不会c/c++语言。没有办法,我就承担了这个有意思的任务。下面通过实战例子,来剖析thrift的应用。
目录:
1.thrift是干什么用的?
2.thrift语法?
3.实战例子
3.1 环境
3.2 安装
3.3 实战例子
4.小结
1.Thrift是干什么用的?
Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 这些编程语言间无缝结合的、高效的服务。Thrift最初由facebook开发,07年四月开放源码,08年5月进入apache孵化器。Thrift允许你定义一个简单的定义文件中的数据类型和服务接口,以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。
2.Thrift语法
请参考网上其他文章。网上很多,不在赘述。重点了解:基本类型、容器、结构体、枚举、服务即可。
2.1基本类型:
bool: 布尔值 (true or false), one byte
byte: 有符号字节
i16: 16位有符号整型
i32: 32位有符号整型
i64: 64位有符号整型
double: 64位浮点型
string: Encoding agnostic text or binary string
Note that: Thrift不支持无符号整型,因为Thrift目标语言没有无符号整型,无法转换
2.2容器:
Thrift容器与流行编程语言的容器类型相对应,采用Java泛型风格。它有3种可用容器类型:
list<t1>: 元素类型为t1的有序表,容许元素重复。
set<t1>:元素类型为t1的无序表,不容许元素重复。
map<t1,t2>: 键类型为t1,值类型为t2的kv对,键不容许重复。
容器中元素类型可以是除了service外的任何合法Thrift类型(包括结构体和异常)。
2.3 枚举和结构体
枚举,和我们平常理解的枚举一样。
这里只强调结构体就是类似于c/c++中的结构体(几乎一模一样)。类似于java中的实体bean。例子如下:
枚举:
enum TweetType {
TWEET, // (1)
RETWEET = 2, // (2)
DM = 0xa, // (3)
REPLY
}
结构体:
struct TxtClass{
1: string text,
2: string classId,
3: double score,
}
2.4 服务
在流行的序列化/反序列化框架(如protocal buffer)中,Thrift是少有的提供多语言间RPC服务的框架。这是Thrift的一大特色。Thrift编译器会根据选择的目标语言为server产生服务接口代码,为client产生stubs。
这里就是thrift自动会生成的方法,我们的服务端也需要器生成的方法中进行编码。例子如下:
service Twitter {
// A method definition looks like C code. It has a return type, arguments,
// and optionally a list of exceptions that it may throw. Note that argument
// lists and exception list are specified using the exact same syntax as
// field lists in structs.
void ping(), // (1)
bool postTweet(1:Tweet tweet); // (2)
TweetSearchResult searchTweets(1:string query); // (3)
// The 'oneway' modifier indicates that the client only makes a request and
// does not wait for any response at all. Oneway methods MUST be void.
oneway void zip() // (4)
}
<!--[if !supportLists]-->1. 3.<!--[endif]-->实战例子
3.1 环境
centOS6.4 64位操作系统
3.2 安装
首先,从官网http://thrift.apache.org/上下载thrift-0.8.0版本,你可以下载最新的版本。
其次,从网上下载ant 和ivy。放在/usr目录下。
Ant下载路径:http://ant.apache.org/
Ivy下载路径:http://ant.apache.org/ivy/
一切准备就绪,即可安装:
3.2.1安装ant和ivy(root用户)
第一步:安装 切复制ivy-2.2.0.jar到/usr/local/apache-ant-1.8.2/lib/目录中
- # tar xzvf apache-ant-1.8.2-bin.tar.gz -C /usr/local
- # tar xzvf apache-ivy-2.2.0-bin-with-deps.tar.gz -C /usr/local
- # cp /usr/local/apache-ivy-2.2.0/ivy-2.2.0.jar /usr/local/apache-ant-1.8.2/lib/
第二步:编辑vim /etc/ profile ,添加如下两行
- export ANT_HOME=/usr/local/apache-ant-1.8.2
- PATH=$ANT_HOME/bin:$PATH
第三步:解压thrift压缩文件。我用的是thrift-0.8.0.tar.gz
- tar zxvf thrift-0.8.0.tar.gz
- 进入到thrift-0.8.0目录
第四步:包的检查、安装(如果缺少包,请安装缺少的包)
- ./configure --prefix=/usr/local/ --with-boost=/usr/local --without-php
- make
- make install
第五步:
在终端输入:thrift –version 查看是否安装成功。
3.3 实战例子
特别注意:如下例子:演示的是thrift-0.7.0版本(因我服务器上安装的此版本)
1.定义thrift文件:user.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.通过thrift的shell工具命令生成c++,java代码框架
- thrift -r --gen cpp user.thrift
- thrift -r --gen java user.thrift
- cp gen-cpp/UserService_server.skeleton.cpp UserServer.cpp
- // This autogenerated skeleton file illustrates how to build a server.
- // You should copy it to another filename to avoid overwriting it.
- #include <string>
- #include <iostream>
- #include "UserService.h"
- #include <config.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;
- using namespace std;
- class UserServiceHandler : virtual public UserServiceIf {
- public:
- UserServiceHandler() {
- // Your initialization goes here
- }
- void add(const User& u) {
- // Your implementation goes here
- cout << "调用add方法" << endl;
- }
- void get(User& _return, const std::string& uid) {
- // Your implementation goes here
- _return.uid = "001";
- _return.uname = "dengqs";
- _return.usex = 1;
- _return.uage = 3;
- cout << "uid = " << _return.uid << endl;
- cout << "调用get方法" << endl;
- }
- };
- int main(int argc, char **argv) {
- int port = 9090;
- 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;
- }
- BOOST_DIR = /usr/include/boost/
- THRIFT_DIR = /usr/local/include/thrift
- LIB_DIR = /usr/local/lib
- GEN_SRC = ./gen-cpp/user_types.cpp ./gen-cpp/user_constants.cpp ./gen-cpp/UserService.cpp
- default: server
- server: UserServer.cpp
- g++ -g -o UserServer -I${THRIFT_DIR} -I${BOOST_DIR} -I./gen-cpp -L${LIB_DIR} -lthrift UserServer.cpp ${GEN_SRC}
- nohup ./UserServer >log 2>&1 &
- ./run.sh
- 或者
- ./UserServie
- import org.apache.thrift.TException;
- import org.apache.thrift.protocol.TCompactProtocol;
- import org.apache.thrift.protocol.TProtocol;
- import org.apache.thrift.transport.TSocket;
- import org.apache.thrift.transport.TTransport;
- import org.apache.thrift.transport.TTransportException;
- import com.intyt.thrift.client.User;
- import com.intyt.thrift.client.UserService;
- public class Demo {
- public void start(){
- try {
- String ip = "10.x.x.x"; //服务端的ip
- int port = 9090;//端口
- TTransport socket = new TSocket(ip,port);
- TProtocol protocol = new TCompactProtocol(socket);
- UserService.Client client = new UserService.Client(protocol);
- socket.open();
- User u = new User();
- u.uid="003";
- u.uname="dengqs_test";
- u.usex=true;
- u.uage=3;
- client.add(u);
- System.out.println(client.get(u.uid));
- socket.close();
- }catch (TTransportException e) {
- e.printStackTrace();
- } catch (TException e) {
- e.printStackTrace();
- }
- }
- public static void main(String[] args) {
- Demo demo = new Demo();
- demo.start();
- }
- }
- thrift应用举例(c/c++作为服务端、java作为客户端)
- thrift应用举例(c/c++作为服务端、java作为客户端)
- netty 服务端作为客户端跳转请求服务端
- 虚拟机centos中java代码实现linux(作为服务端),windows(作为客户端)通信
- Android作为客户端,PC作为服务端:实现网络通信
- Android作为客户端,PC作为服务端:实现网络通信
- Android作为客户端,PC作为服务端:实现网络通信
- Android作为客户端,PC作为服务端:实现网络通信!
- Git服务搭建使用Linux作为服务端,window作为客户端
- Android作为客户端,PC作为服务端:实现网络通信
- Android作为客户端,PC作为服务端:实现网络通信
- Android作为客户端,PC作为服务端:实现网络通信
- Linux作为服务端,Windows作为客户端socket通信
- json作为客户端调用服务端说明
- 引用作为C/C++
- 使用C#作为客户端的PHP服务器上传文件
- C++\C指针作为参数
- Thrift objective C应用
- 关于Url和Uri的区别
- 移动端布局笔记
- linux中的网络端口
- assert断言的用处
- 时间换算(5分)
- thrift应用举例(c/c++作为服务端、java作为客户端)
- Android RecyclerView 使用完全解析
- Spark调优之开发调优
- Mac 终端启动,关闭,重启Apache
- android 切换卡的两种种形式
- Java的构建器(Constructor)
- hibernate 的id的generator class=?
- NAT技术代理服务器
- 树状数组 stars