August 28, 2003

Weblogs.Com Ping の Perl による実装

[ Perl , XML , ウェブログに関すること ]

UserLand が運営する Weblogs.Com は MovableType などのウェブログツールから、Ping と呼ばれる更新通知を受信して、ウェブログの更新情報を XML で配信しているサイトです。Ping の送受信には SOAP や XML-RPC が使われます。大袈裟に言うと、ウェブサービスですね。

Weblogs.Com Ping は仕様が公開されており、Weblogs.Com 以外にも Ping を受け付けるプログラムを実装したサイトはたくさんあります。国内ですと、先日サービスインした Myblog Japandh's memoranda の hirata さんによる ping.bloggers.jp などがあります。

BlogSharesBlogRollingBlogMatcher といったメタブログサービスは、Weblogs.Com を始めとする各 Ping サイトが公開するウェブログ更新情報を元にウェブログを巡回したり、ウェブログの更新通知を行うようになっています。

物は試しにと、Ping サーバを Perl で実装してみました。(公開目的ではなく、実験目的です。)

とりあえず今回は実装が簡単そうな XML-RPC インタフェースのみ考慮しました。XML-RPC インタフェースの仕様は Weblogs.Com XML-RPC interface で公開されています。かなりシンプルな仕様になっています。

Ping する側は、Ping サーバに対して HTTP POST、Content-Type: text/xml で以下の様なリクエストを送信します。

<?xml version="1.0"?>
<methodCall>
  <methodName>weblogUpdates.ping</methodName>
  <params>
    <param>
      <value>NDO::Weblog</value>
    </param>
    <param>
      <value>http://naoya.dyndns.org/~naoya/mt/</value>
    </param>
  </params>
</methodCall>

これは XML-RPC によるメソッド呼び出しのフォーマットで、関数風に書くと、weblogUpdates.ping("NDO::Weblog", "http://naoya.dyndns.org/~naoya/mt/") に等しくなっています。第一引数にウェブログの名前、第二引数にウェブログのURLを渡すよう仕様で決められています。

このリクエストを受信したサーバーは、引数を使って任意の処理をした後、以下のリクエストを Ping 送信元に返却します。

<?xml version="1.0"?>
<methodResponse>
  <params>
    <param>
      <value>
        <struct>
          <member>
            <name>flerror</name>
            <value>
              <boolean>0</boolean>
            </value>
          </member>
          <member>
            <name>message</name>
            <value>Thanks for the ping</value>
          </member>
        </struct>
      </value>
    </param>
  </params>
</methodResponse>

返却される値は構造体を XML-RPC 規則に則ってシリアライズしたものになります。名前が flerror で値が boolean 型、名前が message で値が string 型の二つのメンバで構成される構造体を返却します。flerror が Ping 処理の成否を判定するための返値で、false のときは処理が成功したとみなされます。もし何かしらのエラーを送信元に通知したい場合は、flerror を true (boolean 1)、messags にエラー内容を記述して返却します。

XML-RPC インタフェースの仕様はこの二点のみ。

Perl で XML-RPC インタフェースを実装する場合、色々方法は考えられますが、CPAN の XMLRPC::Transport::HTTP を使うのが簡単です。XMLRPC::Transport::HTTP は SOAP::Lite ディストリビューションに含まれるので、SOAP::Lite をインストールすれば一緒に入ってきます。

サンプルコードは以下のようになります。

#!/usr/local/bin/perl
 
use strict;
use warnings;
use XMLRPC::Transport::HTTP;
 
XMLRPC::Transport::HTTP::CGI->dispatch_to('weblogUpdates')->handle;
 
package weblogUpdates;
 
sub ping {
    my $self = shift;
    my ($name, $url) = @_;
 
    # ここに何かしらの処理を書く
 
    return { flerror => XMLRPC::Data->type('boolean', 0),
             message => "Thanks for the ping" };
}

XML::RPC::Transport::HTTP を使うと XML-RPC サーバが作れますが、サーバを CGI プログラムとして実装することもできるし、スタンドアロンのデーモンとして実装することもできます。ここでは CGI プログラムとして実装しました。

パッケージ weblogUpdates を XML::RPC::Transport::HTTP::CGI->dispatch でディスパッチし、weblogUpdates パッケージに ping メソッドを用意します。この ping メソッドが、先ほどの weblogUpdates.ping("NDO::Weblog", "http://naoya.dyndns.org/~naoya/mt/") に相当します。引数としてウェブログの名前、ウェブログのURLを受け取っています。それぞれの値には、Ping リクエストに含まれている値がちゃんと代入されてきます。

返却する値としてハッシュのリファレンス返せば、XML::RPC::Transport が返却値のシリアライズや XML レスポンスの作成などをやってくれます。楽ちんです。boolean 型を明示的に指定するために XMLRPC::Data->type を使ってます。(明示的に指定しないと自動で判定してくれますが、整数は int 型になってしまうので。)

実験のための簡単な Ping クライアントも実装してみます。クライアントも同じく CPAN モジュールを使えば簡単にできます。SOAP::Lite に含まれる XMLRPC::Lite でもいいですが、ここでは敢えて Frontier::Client を使ってみます。

#!/usr/local/bin/perl
 
use strict;
use warnings;
use Frontier::Client;
 
my $server = Frontier::Client->new( url => 'http://localhost/some/where/ping.cgi',
                                    debug => 1);
my $result = $server->call('weblogUpdates.ping', 
                           'NDO::Weblog', 
                           'http://naoya.dyndns.org/~naoya/mt/');
 
for my $key (keys %$result) {
    print $key, ": ", $result->{$key}, "\n"; 
}

Frontier::Client のコンストラクタの引数に、先ほど書いた CGI プログラム (ここでは ping.cgi ) の URL を指定します。(CGI として正しく動作する場所に設置すること。) あとは、Frontier::Client の call メソッドを使って、XML-RPC 呼び出しを行うのみ。第一引数が XML-RPC メソッド名、以降がそれに与える引数となります。構造体の返却値はハッシュリファレンスで返ってくるので、デリファレンスしていじるのみ。クライアントを実行して "Thanks for the ping" が出力されたら成功です。

なお、Frontier::Client のコンストラクタの引数として debug => 1 としておくと、XML-RPC リクエスト、レスポンスが出力されるので便利です。

# CPAN って素晴らしい。:)

もちろん、この Ping サーバには MovableType などのウェブログツールから Ping (TrackBack Ping ではないです。) を打つことができます。まだ Ping サーバには何も処理を行わせていないので、これだと送信しても無意味ですけど。

Weblogs.Com では Ping 受信結果をアグリゲーションして changes.xml として公開してます。changes.xml の仕様も公開されているので、Ping を受信して、新しい更新情報をもとに changes.xml を更新する処理を書けば自前 Weblogs.Com の完成です。

changes.xml についてと、その処理方法については明日にでも記述します。

Posted by naoya at August 28, 2003 01:57 AM | トラックバック (11)  b_entry.gif
トラックバック [11件]
TrackBack URL: http://mt.bloghackers.net/mt/suck-tbspams.cgi/384
Weblogs.Com changes.xml を Perl で料理する一例
Excerpt: 昨日のエントリ、'Weblogs.Com Ping の Perl による実装' でも少し触れましたが、Weblogs.Com は受信した Ping による更新情報を整理して changes.xml として公開しています。各種メタブログサービスはこの changes.xml に記述された情報を元に、ウェブログを巡回したり、...
Weblog: NDO::Weblog
Tracked: August 29, 2003 02:00 PM
weblogの更新通知 PingサービスをJava Servletで実装
Excerpt: weblogs.comのようなPingサービスの面白い点は、そのリアルタイム性にあります。Googleなどの検索エンジンとの違いを考えつつ、Java ServletでPingサーバーを実装してみました。
Weblog: Goodpic : Surfing Pictures
Tracked: September 9, 2003 05:36 PM
weblogの更新通知 PingサービスをJava Servletで実装
Excerpt: weblogs.comのようなPingサービスの面白い点は、そのリアルタイム性にあります。Googleなどの検索エンジンとの違いを考えつつ、Java ServletでPingサーバーを実装してみました。
Weblog: Goodpic : Surfing Pictures
Tracked: September 9, 2003 05:40 PM
Weblog serviceを使ってみる (2003/12/28)
Excerpt: blogの特徴というのは、清水さんがおっしゃられるように、「コメント」や「トラックバック」、「Ping」といった機能を使うことで、記事を元にしたコミュニケーションやblogサイト間のつながりが生まれるという「横の広がり」だという。blog初心者だけれど、これらを使ってみ
Weblog: きままな写真雑記
Tracked: December 28, 2003 04:47 AM
XML-RPCブックマーク
Excerpt: XML-RPC HOWTO http://www.linux.or.jp/JF/JFdocs/XML-RPC-HOWTO/ XML-RPC 仕様書 http://lowlife.jp/yasusii/stories/9.html msanolog: XML-RPC with SOAP::Lite http://www.semblog.org/msano/archives/000166.html PerlでXML-RPCを始めよう 第1回: WebサービスにXML-RP...
Weblog: VACUUN!
Tracked: February 20, 2004 01:41 AM
2ちゃんねるpingβ
Excerpt: [ブログ] blogる [weblog] スレッドからのpingです。
Weblog: 2ちゃんねる
Tracked: May 22, 2004 04:46 PM
Weblogs.Comその他へ更新Ping通知
Excerpt: ココログを使っている間は、記事を書けばココログTopページの新着記事一覧に出てくれるし、Weblogs.ComやココログPingサーバに更新通知Pingを送ってくれるしで、まあそういう部分からのアクセスも少なからずあったけど、レンタルサーバで独自ドメインで運用となるとやはり...
Weblog: delicious BINARY?
Tracked: May 29, 2004 12:30 AM
Pingサーバー
Excerpt: a href="http://naoya.dyndns.org/~naoya/mt/archives/000423.html">Web...
Weblog: PukiWiki/TrackBack 0.1
Tracked: November 11, 2004 09:38 PM
Pingサーバー
Excerpt: Weblogs.Com Ping の Perl による実装 : NDO::Weblog Weblogs.Com changes.xml を Perl で料理する...
Weblog: PukiWiki/TrackBack 0.1
Tracked: November 11, 2004 09:40 PM
アメリカに行くまでに作るぞ !! (その2)
Excerpt: 私が作りたいものは、例えばgooBlogのトップページみたいなやつで、友人あたり...
Weblog: araitatsuya.net
Tracked: March 5, 2005 10:07 PM
member.2ch2.net
Excerpt: ログインまわり 2ch2.net ログインまわり 2ch2.net Todo member情報をDBに突っ込むところまでできた。 Task ...
Weblog: PukiWiki/TrackBack 0.1
Tracked: September 5, 2005 08:26 PM
コメント [0件]