(I) 時間取得とフォーマット化
ここでは、チャット書き込みされた時間を取得して、プログラムで処理しやすいフォーマット、および表示用のフォーマットを作成しています。
リスト6 多機能チャットプログラム-4 (channelHtl5.htm)
02 | function setutime1(){ //(1) |
03 | var date = new Date(); |
04 | var yy = date.getYear(); |
05 | var mm = date.getMonth() + 1; |
06 | var dd = date.getDate(); |
07 | var hh = date.getHours(); |
08 | var mt = date.getMinutes(); |
09 | var ss = date.getSeconds(); |
10 | if (yy < 2000) { yy += 1900; } //(2) |
11 | if (mm < 10) { mm = "0" + mm; } |
12 | if (dd < 10) { dd = "0" + dd; } |
13 | if (hh < 10) { hh = "0" + hh; } |
14 | if (mt < 10) { mt = "0" + mt; } |
15 | if (ss < 10) { ss = "0" + ss; } |
16 | var utime1 = ""+ yy + mm + dd + hh + mt + ss; //(3) |
19 | function setutime2(utime1){ |
20 | var utime2 = utime1.substr(0, 4) + ":"; |
21 | for (var i = 4; i < 12; i += 2) { |
22 | utime2 += utime1.substr(i, 2)+ ":"; |
24 | utime2 += utime1.substr(i, 2); |
33 | <input type="radio" name="showloc" value="ok" checked />位置表示OK |
34 | <input type="radio" name="showloc" value="no" />位置表示NO |
36 | <input type="button" id="close" value="接続終了" /> |
38 | 名前<input type="text" id="uname" size="12"/> |
39 | Email (必須)<input type="text" id="uemail"/> |
40 | <input type="button" id="send" value=" 書込み "/><br/> |
41 | <textarea id="umsg" rows="5" cols="64"></textarea> |
44 | ステータス<span id="status"></span><br/> |
47 | <input type="button" id="revRemote" value=" App Engineデータ参照 "/> |
48 | <input type="button" id="revLocal" value=" ローカルPCデータ参照 "/> |
49 | <input type="button" id="delLocal" value=" ローカルPCデータ削除 "/> |
50 | <input type="button" id="revGmaps" value=" Google Maps参照 "/> |
52 | <table border="0" width="760"> |
53 | <tbody id="splist" width="760"></tbody> |
リスト6ではsetutime1と setutime2の2つの関数が定義されていますが、それぞれ次のような処理を行っています。
setutime1関数
setutime1では(1)で、Date関数を使用して現在に時刻を取得し、getYear() から getSeconds() の関数で年月日時分秒 を取得していますが、 年4桁、月以下か2ケタの揃えるための処理を(2)からの処理で行っています。以上で処理された値を(3)でutime1に代入していますが、この値は数字だけですべて同じ桁数になり、ソートや数値操作を行い易いデータ形式になっています。
setutime2関数
setutime2では、setutime1で取得された数値並びの年月日時分秒に対して、単位表示の間にコロン(:)を挿入して、人間が見やすい形式に変換しています。
コラム:[Ajax非同期型でのサーバ通信とタイマ処理]
このサンプルでは、gaedirectのChannelサーバに対するプッシュデータ送信でWeb Workersのバックグラウンドスクリプトを使用していますが、Channelサーバへのデータ送信は非同期で行われます。つまりレスポンスはChannelイベント(socket.onmessage)から受信されるので、送信に対するレスポンスは直ちに返され、バックグラウンドで行う意味はあまりありませんでした。
しかし、一般的にはサーバからのレスポンスはサーバ側での処理完了後に返されるので、環境やアプリケーション内容によっては時間が掛かることもあり、特に参照系ではかなり待たされるようなケースも出てきます。このような場合、バックグラウンドスクリプトを使用すれば、サーバからのレスポンスが返されるまでの時間も、フォアグラウンドでの会話型処理はそれを意識することもなく継続することができるようになります。
リスト7 Ajax非同期型でのサーバ通信とタイマ処理
01 | onmessage = function(e) { |
02 | var timerId = setInterval("timeout()", 3000 ); //(1) |
03 | var xhr = new XMLHttpRequest(); |
04 | xhr.open("post", "/channelapi"); |
05 | xhr.setRequestHeader("If-Modified-Since", "01 Jan 2000 00:00:00 GMT"); //(2) |
06 | xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); |
07 | xhr.onreadystatechange = function(){ |
08 | if(xhr.readyState == 4){ //(3) |
09 | if(xhr.status == 200){ //(4) |
10 | clearInterval(timerId); //(5) |
11 | var res = xhr.responseText; |
12 | postMessage("送信完了:"+res); //(6) |
18 | function timeout(){ //(7) |
19 | clearInterval(timerId); //(8) |
21 | postMessage("タイムアウトで通信が切断されました。"); //(10) |
リスト7はリスト6のAjax非同期通信を「同期型」に変えたサンプルですが、このサンプルでは、タイマを使用しています。
リストでは(1)でタイマ設定を行っていますが、setIntervalでは、第二引数に指定した時間(ここでは3000ミリ秒)経過すると第一引数に指定した関数が呼び出されます。その後AjaxのPOST同期型での「非同期」通信を行っていますが、(2)はキャッシュデータを使用しないようにするためのHTTPヘッダ追加です。
サーバからのレスポンス受信が完了すると(3)と(4)のif文が満足されて、次のステップに移りますが、ここで直ちに、タイマ設定をクリアして(5)、受信データをpostMessageでフォアグラウンドのスクリプトに送っています。ここでもしタイマで指定した時間内にレスポンスが返らない場合は、(7)のタイマ関数が呼び出されて、タイマ設定のクリア(8)、非同期通信のアボート(9)を行った後、(10)postMessageのでタイムアウトメッセージをフォアグラウンドスクリプトに返しています。