Gauche-XMPPライブラリをリリース!

GaucheXMPPクライアントを作ろう!
Gauche-xmpp-1.0.tgz

tweet.IMを使えばTwitterクライアントにもなる!
ただし、Google Talkには直接繋げません。(私がTLSをまだ実装していないので)
jabber.jpや、ローカルで立てたejabberdに繋いで楽しんでください。

簡単な説明

XMPPには以下の段階があります。

  1. 接続
  2. 認証
  3. リソースバインド
  4. セッションセット
  5. プリセンス
  6. メッセージのやりとり
  7. ...
  8. 切断

このライブラリはシンプルさを目指したので、この段階に逐一沿って、
メッセージのやりとりまでに5個も関数を呼ぶ必要がありますが、勘弁してください。

  • xmpp-connect で接続。
    • おなじみの call-with-xmpp-connection もあるのでどうぞ。
  • xmpp-auth で認証。認証方法を自動で選んで使ってくれます
    • digest-md5暗号認証を最優先し、次点にplain認証, anonymous認証
    • 手動がよければ xmpp-sasl-digest-md5 などを直接呼んでください。
  • xmpp-bind でリソースバインド。
  • xmpp-session でセッションセット。
  • xmpp-presence でプリセンス。
  • xmpp-message でメッセージを送る。
  • xmpp-receive-stanza で受信。受信するまでブロックします。
    • stanzaの解釈はあなたの仕事です(ぎゃー)。届いたSXMLを渡すので、sxpathを駆使して頑張ってください。
  • xmpp-disconnect で切断。

エコーbot

#!/usr/bin/env gosh

(use sxml.sxpath)
(use rfc.xmpp)

(define-constant hostname     "localhost")
(define-constant yourname     "romeo")
(define-constant yourpass     "romeo")
(define-constant yourresource "Home")

#|
 <message type="chat" to="romeo@localhost" from="juliet@localhost">
   <body>Hi, Romeo.</body>
 </message>
 のSXML表現
 (jabber:client:message (@ (type "chat") (to "romeo@localhost") (from "juliet@localhost"))
   (jabber:client:body "Hi, Romeo."))
 からsxpathでメッセージの情報を取り出す。
 取り出せたら(差出人 . 本文)を返す。
 メッセージでなかったら #f を返す。
|#
(define (parse-message sxml)
  (and-let* ((from ((if-car-sxpath '(jabber:client:message @ from *text*)) sxml))
             (body ((if-car-sxpath '(jabber:client:message jabber:client:body *text*)) sxml)))
    (cons from body)))

(define (main args)
  ;;接続
  (call-with-xmpp-connection hostname
    (lambda (c)
      ;;認証
      (xmpp-auth c yourname yourpass)
      ;;リソースバインド
      (xmpp-bind c yourresource)
      ;;セッションセット
      (xmpp-session c)
      ;;プリセンス
      (xmpp-presence c)
      ;;無限ループってこわくね?
      (while #t
        (and-let* ((m (parse-message (xmpp-receive-stanza c))))
          ;;エコー
          (xmpp-message (c :to (car m))
            (cdr m)))))))