nDiki : RPC::XML

2004年8月29日 (日)

XML-RPC - Java クライアントと Perl サーバ

Java プログラムと Perl プログラムとの連携に XML-RPCが使えないか検討。 まずは実験。

Perl

RPC::XMLモジュールを使う。

 #!/usr/bin/perl -w

 use strict;
 use RPC::XML::Server;

 my $server = RPC::XML::Server->new(port => 9876);
 $server->add_method( {name => 'Perl.eval',
                       signature => [ 'struct string' ],
                       code => sub { warn $_[1]; return {value => eval $_[1]}}});
 $server->server_loop;

引数の文字列を eval した結果を文字列で返す危険な手続き。

Java

いろいろライブラリがあり迷う。 Apache XML-RPCが簡単そうなのでまずはこれで。1.2-b1 を使用。

 import java.util.Vector;
 import java.util.Hashtable;
 import java.io.IOException;

 import org.apache.xmlrpc.XmlRpcClient;
 import org.apache.xmlrpc.XmlRpcException;

 public class XMLRPCClient {
   public static void main(String[] args) {
     String url = args[0];
     String methodName ="Perl.eval";
     Vector params = new Vector();
     params.add(args[1]);
     try {
       XmlRpcClient client = new XmlRpcClient(url);
       try {
         //String result = (String)client.execute(methodName, params);
         //System.out.println(result);
         Hashtable result = (Hashtable)client.execute(methodName, params);
         System.out.println(result.get("value"));
       } catch (XmlRpcException ex) {
         System.out.println(ex.getMessage());
       }
     } catch (IOException ex) {
       ex.printStackTrace();
     }
   }
 }

Perl 側でプログラムを起動しておいて実行。

 java -classpath .:xmlrpc-1.2-b1.jar \
   XMLRPCClient http://localhost:9876/ "3 + 5"

8 が出力される。成功。簡単。

[ 8月29日全て ]

2004年8月31日 (火)

RPC::XML のかわりに XMLRPC::Lite

Windows の ActiveState 5.6.1 では RPC::XML の make test が通らない。 がっかり。 かわりに、SOAP::Liteに入っている XMLRPC::Lite を使ってみる。

 #!/usr/bin/perl -w

 use strict;
 use SOAP::Lite +trace => qw(trace);
 use XMLRPC::Transport::HTTP;

 my $daemon = XMLRPC::Transport::HTTP::Daemon
   ->new(LocalPort => 9876)
   ->dispatch_to('Server');

 $daemon->handle;

 package Server;

 sub evalcode {
   warn $_[1];
   return +{ value => eval $_[1] };
 }

 1;

名前の関係から Perl.eval を Server.evalcode に変更した以外は、RPC::XMLの実験の時と一緒。 クライアントは前回の Java プログラム(メソッド名のみ上記のように修正)。

こちらは ActiveState 5.6.1 でも動作。一部ライブラリが warning を出す以外いまのおころ問題無し。Linux 環境でも warning は出る。ライブラリの undefined 扱いの問題のようだ。実害は無さそう。 SOAP::Lite を 0.55 から 0.60a に上げると少し warning が減る(無くならない)。

機能的には RPC::XML の方が使いやすそうだが、SOAP::Lite の方がメジャーという強みがある。ActivePerl 5.6.1 にも標準でバンドルされているし。

[ 8月31日全て ]

2004年9月14日 (火)

XMLRPC::Lite + 自前の HTTP::Daemon サーバ

既に HTTP::Daemon で作成されているHTTPサーバで、XML-RPC インタフェースを提供したい。 前回のチェックで XMLRPC::Lite を使う事にした(RPC::XMLActivePerl 5.6.1 build638 でテストが通らない)。 このパッケージで用意されているサーバ向けモジュールは、主に単独CGI プログラムで使うモジュールと、自前で HTTP::Daemon をまわすサーバタイプ。

そのままでは使えないので、以下のように。

  1. XMLRPC::Transport::HTTP::CGI のサブクラスを作成し、handle をオーバライドする。中身は SOAP::Transport::HTTP::Server::handle を呼ぶだけ (SUPER::handle では駄目)。
  2. XML-RPC リクエストがきたら、上記インスタンスの request メソッドで HTTP::Request オブジェクトを渡す。
  3. handle を実行。
  4. response メソッドで HTTP::Response を受け取り、クライアントに送信。

handle メソッドで入出力をさせないようにするのがポイント。

[ 9月14日全て ]

About

Naney Naneymx

Naney (なにい) です。株式会社MIXIで SNS 事業の部長をしています。

※本サイトの内容は個人的見解であり所属組織とは関係ありません。

Process Time: 0.02185s / load averages: 0.50, 0.32, 0.27