[[ocaml-nagoya]]
#contents

* ThriftでOCamlクライアントを書く [#hb5016a6]

Thriftはいろんな言語で利用可能
C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk, and OCaml.

- OCaml用パッチが必要かも? https://issues.apache.org/jira/browse/THRIFT-125

** Hello World(サーバーはC++、クライアントはOCaml) [#qec0d9e3]
IDL(インターフェース定義言語)

 service Hello
 {
  string hello(1: string name)
 }

Thriftでサーバー(C++)、クライアント(OCaml)を生成

  $ thrift --gen cpp --gen ocaml hello.thrift

** サーバーロジックを書く [#ce0becbb]

Hello_server.skeleton.cpp

 class HelloHandler : virtual public HelloIf {
  public:
   HelloHandler() {
     // Your initialization goes here
   }
 
   void hello(std::string& _return, const std::string& name) {
     // Your implementation goes here
     _return.append("Hello ").append(name);
   }
 };

** サーバーをコンパイル [#p1f2eb95]

  $ g++ -g Hello_server.skeleton.cpp Hello.cpp -o Hello_server -lthrift -I/usr/local/include/thrift

** クライアントを書く [#y6d79ab5]

Hello_client.mlを新規作成して内容はこうする。

 open Thrift;;
 open Hello_types;;
 
 let s = new TSocket.t "localhost" 9090;;
 let p = new TBinaryProtocol.t s;;
 let c = new Hello.client p p;;
 
 s#opn;
 print_string (c#hello "Gemma");
 print_char '\n';
 s#close;
 
** クライアントをコンパイルする [#d58f68ca]

Makefileを使うべし。

 SOURCES = ./gen-ocaml/hello_types.ml ./gen-ocaml/hello_consts.ml ./gen-ocaml/Hello.ml Hello_client.ml
 RESULT = test_client
 INCDIRS = "./Desktop/thrift/lib/ocaml/src/" "./gen-ocaml/"
 LIBS = unix thrift
 all: nc
 OCAMLMAKEFILE = ./Desktop/thrift/lib/ocaml/OCamlMakefile
 include $(OCAMLMAKEFILE)
 

このMakefileの実行結果

 make[1]: ディレクトリ `/home/teruaki' に入ります
 ocamldep -I ./gen-ocaml/ Hello_client.ml > ._d/Hello_client.d
 ocamldep -I ./gen-ocaml/ gen-ocaml/Hello.ml > ._d/./gen-ocaml/Hello.d
 ocamldep -I ./gen-ocaml/ gen-ocaml/hello_consts.ml > ._d/./gen-ocaml/hello_consts.d
 ocamldep -I ./gen-ocaml/ gen-ocaml/hello_types.ml > ._d/./gen-ocaml/hello_types.d
 make[1]: ディレクトリ `/home/teruaki' から出ます
 make[1]: ディレクトリ `/home/teruaki' に入ります
 ocamlc -c -I ./gen-ocaml/ -I ./Desktop/thrift/lib/ocaml/src/ -I ./gen-ocaml/ gen-ocaml/hello_types.mli
 ocamlopt -c -I ./gen-ocaml/ -I ./Desktop/thrift/lib/ocaml/src/ -I ./gen-ocaml/ gen-ocaml/hello_types.ml
 ocamlopt -c -I ./gen-ocaml/ -I ./Desktop/thrift/lib/ocaml/src/ -I ./gen-ocaml/ gen-ocaml/hello_consts.ml
 ocamlc -c -I ./gen-ocaml/ -I ./Desktop/thrift/lib/ocaml/src/ -I ./gen-ocaml/ gen-ocaml/Hello.mli
 ocamlopt -c -I ./gen-ocaml/ -I ./Desktop/thrift/lib/ocaml/src/ -I ./gen-ocaml/ gen-ocaml/Hello.ml
 ocamlopt -c -I ./gen-ocaml/ -I ./Desktop/thrift/lib/ocaml/src/ -I ./gen-ocaml/ Hello_client.ml
 ocamlopt \
 				  \
 				  -I ./gen-ocaml/  -I "./Desktop/thrift/lib/ocaml/src/" -I "./gen-ocaml/"    -ccopt -L./gen-ocaml/    unix.cmxa thrift.cmxa    -o tc \
 				./gen-ocaml/hello_types.cmx ./gen-ocaml/hello_consts.cmx ./gen-ocaml/Hello.cmx Hello_client.cmx
 make[1]: ディレクトリ `/home/teruaki' から出ます

**実行 [#b1124b3e]

***サーバーを立ち上げる [#t1ecd1a6]
 $ gen-cpp/Hello_server
 Thrift: Wed Sep 24 17:37:19 2008 TServerSocket::listen() IPV6_V6ONLY Protocol not available

***クライアントを立ち上げる [#oe39713e]
  $ ./test_client
  Hello Gemma

**クライアントのソースを比べる [#q42d8cb1]

上で使ったOCaml製クライアント

 open Thrift;;
 open Hello_types;;
 
 let s = new TSocket.t "localhost" 9090;;
 let p = new TBinaryProtocol.t s;;
 let c = new Hello.client p p;;
 
 s#opn;
 print_string (c#hello "Gemma");
 print_char '\n';
 s#close;
 

Perl製クライアント

 use lib './gen-perl';

 ## Thrift インストール時にインストールされているライブラリ群
 use Thrift;
 use Thrift::BinaryProtocol;
 use Thrift::Socket;
 
 ## IDL から gen-perl/ 以下に生成されたライブラリ
 use Hello;
 
 my $transport = Thrift::Socket->new('localhost', 9090);
 my $client = HelloClient->new( Thrift::BinaryProtocol->new($transport) );
 
 $transport->open();
 
 printf "%s\n", $client->hello("Gemma");
 
 $transport->close();


Ruby製クライアントは試してないけど、きっとこんな感じ。

 require 'thrift/transport/tsocket'
 require 'thrift/protocol/tbinaryprotocol'
 require 'Hello'
 
 transport = TSocket.new('localhost', 9090)
 client = Hello::Client.new( TBinaryProtocol.new(transport))
 
 transport.open
 
 puts client.hello("Gemma")
 
 transport.close
 

言語がちがってもそっくりだ!

サーバーもC++に限らず、いろんな言語で書ける。
トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS