thrift初体验
使用thrift实现java调用c++实现的简单webservice ? 首先是安装thrift,这花费了不少时间。 关于安装步骤,apache的官方说明已经比较详细了: ? http://wiki.apache.org/thrift/ThriftRequirements http://wiki.apache.org/thrift/ThriftInstallation ? 看起来依赖的库很多,但其实关键的也就是
boost ant ivy slf4j byacc ? (安装的具体依赖关系需要继续验证) ? 1.首先需要定义一个service,也就是新建一个.thrift文件。 在任意位置创建一个文件夹作为项目目录,下面到操作如无说明均是在此目录下进行。 让我们来创建一个.thrift文件吧: 文件名:jobsm.thrift 文件内容:
? struct JobInfo { ??1: i32 jobid = 0, ??2: string user, } ? service JobScheduler{ ? ?? void ping(), ? ?? bool addJob(1:JobInfo job), ? ?? JobInfo getJob() } ? ? 2.使用c++构建server端: 通过thrift命令生成cpp代码: $ thrift -r --gen cpp jobsm.thrift 成功后我们会见到生成的gen-cpp文件夹,进入gen-cpp/,可以看到很多自动生成的c++源文件,创建我们自己的server代码: 文件名: JobScheduler_server.cpp 文件内容:
// This autogenerated skeleton file illustrates how to build a server. // You should copy it to another filename to avoid overwriting it. ? #include <iostream> #include <queue> ? #include "JobScheduler.h" #include <protocol/TBinaryProtocol.h> #include <server/TSimpleServer.h> #include <transport/TServerSocket.h> #include <transport/TBufferTransports.h> ? using namespace ::apache::thrift; using namespace ::apache::thrift::protocol; using namespace ::apache::thrift::transport; using namespace ::apache::thrift::server; ? using boost::shared_ptr; ? class JobSchedulerHandler : virtual public JobSchedulerIf { ? ?private: ??std::queue<JobInfo> container; ? ?public: ??JobSchedulerHandler() : container() { ?? ?// Your initialization goes here ??} ? ??void ping() { ?? ?// Your implementation goes here ?? ?printf("run ping/n"); ??} ? ??bool addJob(const JobInfo& job) { ?? ?// Your implementation goes here ?? ?std::cout<<"add job's id is "<<job.jobid<<std::endl; ?? ?std::cout<<"add job's user is "<<job.user<<std::endl; ?? ?container.push(job); ?? ?printf("run addJob/n"); ??} ? ??void getJob(JobInfo& _return) { ?? ?// Your implementation goes here ?? ?_return = container.front(); ?? ?container.pop(); ?? ?std::cout<<"pop job's id is "<<_return.jobid<<std::endl; ?? ?std::cout<<"pop job's user is "<<_return.user<<std::endl; ?? ?printf("run getJob/n"); ??} ? }; ? int main(int argc,char **argv) { ??int port = 9090; ??shared_ptr<JobSchedulerHandler> handler(new JobSchedulerHandler()); ??shared_ptr<TProcessor> processor(new JobSchedulerProcessor(handler)); ??shared_ptr<TServerTransport> serverTransport(new TServerSocket(port)); ??shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory()); ??shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory()); ? ??TSimpleServer server(processor,serverTransport,transportFactory,protocolFactory); ??server.serve(); ??return 0; }
然后写一个简单的makefile:
BOOST_DIR = /usr/local/boost/include/boost-1_33_1/
THRIFT_DIR = /usr/local/include/thrift
LIB_DIR = /usr/local/lib
GEN_SRC = ./jobsm_types.cpp ./JobScheduler.cpp
default: server
server: JobScheduler_server.cpp
g++ -o CppServer -I${THRIFT_DIR} -I${BOOST_DIR} ?-I../gen-cpp -L${LIB_DIR} -lthrift JobScheduler_server.cpp ${GEN_SRC}
clean:
$(RM) -r CppServer
make成功后,可以看到可执行文件CppServer。
$ ./CppServer 后服务就算是启动了。
3.使用java构建客户端
类似的,使用thrift命令生成java代码
$ thrift -r --gen java jobsm.thrift 成功后我们会见到生成的gen-java文件夹,进入gen-java/,可以看到很多自动生成的java文件,创建我们自己的client代码: 文件名:JavaClient.java 文件内容:
import org.apache.thrift.TException; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; ? import java.util.AbstractMap; import java.util.HashMap; import java.util.HashSet; import java.util.ArrayList; ? public class JavaClient { ??public static void main(String [] args) { ? ?? ?try{ ?? ? ?TTransport transport = new TSocket("localhost",9090); ?? ? ?TProtocol protocol = new TBinaryProtocol(transport); ?? ? ?JobScheduler.Client client = new JobScheduler.Client(protocol); ? ?? ? ?transport.open(); ? ?? ? ?for(int i=0; i<args.length; i++) { ?? ? ? ?System.out.println(args[i]); ?? ? ?} ? ?? ? ?client.ping(); ?? ? ?System.out.println("ping()"); ? ?? ? ?JobInfo job = new JobInfo(); ?? ? ?if(args.length > 0 && args[0] != null) ?? ? ? job.setJobid(Integer.parseInt(args[0])); ?? ? ?else ?? ? ? ?job.setJobid(0); ?? ? ?if(args.length >1 && args[1] != null) ?? ? ? ?job.setUser(args[1]); ?? ? ?else ?? ? ? ?job.setUser("default"); ? ?? ? ?client.addJob(job); ?? ? ?System.out.println("addJob"); ? ?? ? ?JobInfo job2 = client.getJob(); ?? ? ?System.out.println("getJob. JobId is "+ job2.getJobid() + ". JobUser is " + job2.getUser()); ? ?? ?} catch (TException x) { ?? ? ?x.printStackTrace(); ?? ?} ??} } ? 让我们使用ant来编译这个java工程吧,在gen-java目录下新建一个build.xml文件 文件内容:
<project name="jobscheduler" default="jobscheduler" basedir="."> ? ??<description>JobScheduler</description> ? ??<property name="src" location="./" /> ??<property name="gen" location="./" /> ??<property name="build" location="build" /> ? ??<path id="libs.classpath"> ?? ?<pathelement path="/usr/thrift-0.5.0/lib/java/libthrift.jar" /> ?? ?<fileset dir="/usr/thrift-0.5.0/lib/java/build/ivy/lib"> ?? ? ?<include name="*.jar" /> ?? ?</fileset> ??</path> ??<path id="build.classpath"> ?? ?<path refid="libs.classpath" /> ?? ?<pathelement path="${gen}" /> ??</path> ? ??<target name="init"> ?? ?<tstamp /> ?? ?<mkdir dir="${build}"/> ??</target> ? ??<target name="compile" depends="init"> ?? ?<javac srcdir="${gen}" destdir="${build}" classpathref="libs.classpath" /> ?? ?<javac srcdir="${src}" destdir="${build}" classpathref="build.classpath" /> ??</target> ? ??<target name="jobscheduler" depends="compile"> ?? ?<jar jarfile="jobscheduler.jar" basedir="${build}"/> ??</target> ? ??<target name="clean"> ?? ?<delete dir="${build}" /> ?? ?<delete file="jobscheduler.jar" /> ??</target> ? </project> ? 好了,执行 $ ant 成功后就生成了build目录和一个新的jar包,再写一个shell来运行客户端吧。 文件名:JavaClient 文件内容:
#!/bin/sh ? LIB_DIR=/usr/thrift-0.5.0/lib/java/ IVY_DIR=$LIB_DIR/build/ivy/lib/ java -cp $IVY_DIR/*:$LIB_DIR/libthrift.jar:jobscheduler.jar JavaClient $1 $2 ? 运行客户端: $ ./JavaClient 123 userABC 可以看到server端和client端都有对应的显示。 说明一个简单的webservice成功完成! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |