XMPP on Google App Engine
XMPPってなんだ?
よくわかっていないのだが,インスタントメッセージを標準化しようというプロトコルらしい.こちらに非常によくまとまっているのだが,プロトコルとしてはメイルにかなり近いようだ.アドレスもメイルと同じ表現で,XXX@domain.nameと書く.サーバをDNSで引いてそこに送りつける,という部分も同じ.
これをGAEで使うとなにができるようになるか,というと,Google Talkなどから情報を入れたり,Google Talkにノーティフィケーションを出したりすることができる.たとえば,予定管理アプリなら,時間になったらIMが飛んでくる,みたいなことができる.私のように常にGmailを開いているものには便利だろう.
以下はApp Engineのページを参考にまとめてみる.
アドレス
GAEアプリには アプリID@appspot.com というアドレスが自動的に与えられる.また,
XXXX@アプリID.appspotchat.com
というアドレスも利用できる.XXXXは,任意の文字列.appspotchat.com というドメインになっていることに注意.
ちなみにアプリに複数のバージョンがある場合,当然これらのアドレスはデフォルトのアプリで処理される.ただし,
XXXX@バージョン.latest.アプリID.appspotchat.com
というアドレスで,各バージョンにメッセージを送ることができる.
デフォルトでないアプリがメッセージを送信した場合には,
アプリID@バージョン.latest.アプリID.appspotchat.com
からの送信となる.
送信
送信は,メイルとかとほとんど同じ.アドレスとボディを設定して,送るだけ.簡単.
フォームから送信できるものを作ってみる.まずはフォーム.
<form action="/send" method="post"> <div>to: <input name="to"/></div> <textarea name="body" rows="2" cols="40" ></textarea> <div><input type="submit" value="Submit" /></div> </form>
サーブレットはこんな感じ.
import java.io.IOException; import javax.servlet.http.*; import com.google.appengine.api.xmpp.*; @SuppressWarnings("serial") public class XMPPSenderServlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException { res.setContentType("text/html"); String to = req.getParameter("to"); String body = req.getParameter("body"); JID jid = new JID(to); String msgBody = body; Message msg = new MessageBuilder() .withRecipientJids(jid) .withBody(msgBody) .build(); boolean messageSent = false; XMPPService xmpp = XMPPServiceFactory.getXMPPService(); if (xmpp.getPresence(jid).isAvailable()) { SendResponse status = xmpp.sendMessage(msg); messageSent = (status.getStatusMap().get(jid) == SendResponse.Status.SUCCESS); if (messageSent) res.getWriter().println("<h2>Message Sent!</h2>"); else res.getWriter().println("<h2>Failed!</h2>"); } else { res.getWriter().println("<h2>the address " + to + " is not available</h2>"); } } }
<servlet> <servlet-name>xmppsender</servlet-name> <servlet-class>myTest.XMPPSenderServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>xmppsender</servlet-name> <url-pattern>/send</url-pattern> </servlet-mapping>
Gmailのアドレスに送るとチャットウィンドウにメッセージが現れる.
受信
GAEにおけるXMPPの受信は,特定のURLへのリクエストという形で行われる.これは,GAEで言うところの,Web Hookというパターンで,スケジュールド・タスクやタスクキューでもおなじパターンが使われている.
受信するためには,以下をおこなえばよい.
appengine-web.xmlに設定
下記をappengine-web-appタグの中に書くだけ.
<inbound-services> <service>xmpp_message</service> </inbound-services>
ハンドルサーブレット
サーブレットはこんな感じ.
import java.io.IOException; import javax.servlet.http.*; import com.google.appengine.api.xmpp.*; @SuppressWarnings("serial") public class XMPPReceiverServlet extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException { XMPPService xmpp = XMPPServiceFactory.getXMPPService(); Message message = xmpp.parseMessage(req); System.err.println("from: "+ message.getFromJid()); System.err.println("body: "+ message.getBody()); } }