Closure Library には XMLHttpRequest のラッパーである XhrIo が用意されている。
Asynchronous XMLHttpRequests with XhrIo - Closure Library - Google Code
これを使うと簡単にサーバとの通信が行える。こんな感じ(Googleのページより引用)。
goog.net.XhrIo.send(dataUrl, function(e) {
var xhr = e.target;
var obj = xhr.getResponseJson();
log('Received Json data object with title property of "' +
obj['title'] + '"');
alert(obj['content']);
});
この XhrIo を使って複数のリクエストを扱う用途で XhrIoPool と XhrManager が用意されている。
XhrIoPool (Closure Library API Documentation - JavaScript)
XhrManager (Closure Library API Documentation - JavaScript)
XhrIoPool はその名の通りで、複数の XhrIo のインスタンスをプールして使いまわす用途で使う。XhrManager はその XhrIoPool を内部に持っていて複数リクエストを簡単に扱えるようにしたもの。XhrIoPool を使って自前で実装する方法もあるが、特別問題が無い限りは XhrManager を使った方が楽(※XhrIoPool を使った場合、インスタンスの開放やイベントの管理などを自前でやらなければならない)。
今回はこの XhrManager を試してみた。コードはこんな感じ。
xhrio1.html
<script>goog.require('goog.net.XhrManager');
</script>
<script>
var xhrm_ = new goog.net.XhrManager();
function output(msg) {
var console = goog.dom.$('console');
console.innerHTML = console.innerHTML + msg + "<br/>";
}
function handleResponse(e) {
var xhr = e.target;
output(xhr.getStatus() + " : " + xhr.getResponseText());
}
function start(e) {
for (i=0; i < 10; i++) {
xhrm_.send(
i,
'/echo?name=' + i,
'GET',
null,
{},
1,
handleResponse);
output('send: ' + i);
}
}
</script>
基本的には (1)XhrManagerのインスタンスを作り、(2) send()で送信するだけ。上のサンプルでは 10回 send を実行し、結果を画面に書き出している。
呼び出している /echo はこんな感じ ※GAEで動作。
import os, time
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext.webapp import template
class MainHandler(webapp.RequestHandler):
def get(self):
self.response.out.write(self.request.get('name'))
def main():
application = webapp.WSGIApplication(
[('/echo', MainHandler),
], debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
単純に name パラメータの内容を書き出すだけ。これを表示することで、何番目のリクエストが処理されているかがわかる。
実行するとこんな感じ。
XhrManager.send は通信結果を待たずに 10本連続して実行される(非同期)。画面上 send: 0, 1,.. と表示されているのがそう。その後、処理の終わったものから 200: 0 (ステータスコード:id)と表示されていく。処理は並行実行されて、送信順とは違った順番となっているのがわかる。