Wassr というすばらしいサイトがあるのですが、そのサイトでは XMPP でユーザーの更新情報を得ることができたり、発言情報をえたりできます。

このサイトで、それを実現させているのは、bradfitz の DJabberd というソフトウェアみたいです。これを使うと、容易に XMPP Server を構築することができます。Perl でできているので、割と簡単につくれます。もちろん bradware なので、bradware っぽい感じではあります。わからないことがあったら Livejournal のコードを読む必要があるので要注意です。

DJabberd は Danga::Socket を使った IO 多重化の1スレッドで動いています。Danga::Socket で構築されていますので、Gearman::Client::Async を使うことができます。というか、基本的に重い処理はすべて Gearman にやらせるようにしないと、サーバーがふんづまりますので、基本的にはすべての処理は Gearman にやらせるようにします。


さて、そんな DJabberd ですが、Wassr では

  • Wassr::DJabberd::RosterStorageAlwaysBoth
  • Wassr::DJabberd::Bot
  • Wassr::DJabberd::AdminExtension

という3つのモジュールを定義しているようです。


RosterStorageAlwaysBoth というのは、とりあえず話しかけてきた人を全員友達扱いにします。


Bot は、その名のとおりボットのコアです。DJabberd::Bot を継承しています。DJabberd::Bot はソース読まないと使い方わからないので、がんばって解読します。基本的には process_text というメソッドを上書きすればいい。それだけです。

    # $text is flagged utf8.
    # $from is DJabberd::JID
    # $from->as_bare_string; : jid string
    # $ctx  is DJabberd::BotContext
    # $ctx->reply required 'flagged utf8 string'

というような引数の状況でよばれます。jid というのは、Jabber ID の略で、ユーザーの識別符号ですね。DJabberd の中では DJabberd::JID というオブジェクトで表現されています。

さて、これで済めば、なにも問題はないのですが、DJabberd::Bot はエラーの処理がちゃんとできてなくて、エラーパケットもそのまま process_text メソッドにわたってきます。しかしながら、エラーパケットであるという情報を得る手段が process_text の引数にはありません。なので、send_stanza メソッドを ad-hoc に拡張しています。

sub send_stanza {
    my ($self, $stanza) = @_;

    if ($stanza->isa('DJabberd::Message')) {

######### XXX START TOKUHIROM PATCH
        if ($stanza->attr('{}type') ne 'chat') {
            warn "unknown packet type " . $stanza->attr('{}type');
            return;
        }
######### XXX END TOKUHIROM PATCH

以下略


AdminExtesion というのは、DJabberd の admin port(perlbal の admin port みたいなもの) のコマンドを拡張しているだけの存在です。DJabberd::Connection::Admin::CMD_* を定義して、admin port から情報を流し込めるようにしています。


■GOOD JOB!
この記事よいネ!クリック!→