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成功完成!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章