リバースAJAXを行う
ここまでの機能は、既におなじみになっているAJAXの機能「非同期通信」で実現されていました。これは、JavaScriptを使ってクライアントからサーバに通信をし、必要な情報を受け取るというものです。これはすばらしい技術ですが、一つだけ欠点があります。それは「常に一方通行でしか動かない」という点です。
例えば、「必要に応じてサーバからクライアントを呼び出し操作する」といったことはできません。まぁ、これはAJAXに限らず、Webという仕組みそのものがそういうことができないようになっているのですが……。DWRの2.0より追加された「リバースAJAX」は、その常識を覆してしまいました。これは、サーバからクライアントを呼び出し操作できるのです!
これには、いくつかの修正が必要になります。順にやっていきましょう。まず、web.xmlのサーブレットのタグにリバースAJAXのための記述を追加します。
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>pollAndCometEnabled</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
続いて、リバースAJAXするための処理をBean側に追加します。ここでは、MyBeanManagerクラスに、すべてのクライアントにメッセージを一斉送信するためのメソッドを追加することにしましょう。
// import org.directwebremoting.WebContext;
// import org.directwebremoting.WebContextFactory;
// import org.directwebremoting.proxy.dwr.Util;
// addを修正する
public void add(String name,String title,String msg){
String s1 = this.getEscapedString(name);
String s2 = this.getEscapedString(title);
String s3 = this.getEscapedString(msg);
MyBean bean = new MyBean(s1,s2,s3);
data.add(bean);
this.setMessage("「" + s1 + "」さんから投稿がありました。");
}
// 追加するメソッド
public void setMessage(String s1){
WebContext context = WebContextFactory.get();
String page = context.getCurrentPage();
Collection sessions = context.getScriptSessionsByPage(page);
Util util = new Util(sessions);
util.setStyle("lastmsg","color","#0000ff");
util.setValue("lastmsg",s1);
}
わかりますか? addメソッドを修正し、setMessageメソッドを新たに追加します。これに付随して、いくつかのimportが必要となります。これで、addするとすべてのクライアントにメッセージを送信する機能が用意できました。
このseMessageでは、以下のような手順に沿ってリバースAJAXを実現しています。
1.WebContextFactory.getを呼び出し、WebContextインスタンスを取得する。
2.WebContextのgetCurrentPageを呼び出し、ページのStringを得る。
3.WebContextのgetScriptSessionsByPageでセッションのCollectionを取得する。
4.Collectionを引数にしてUtilクラスのインスタンスを生成する。
5.Utilのメソッド(setStyle、setValue)を呼び出して、全セッションに処理を送信する。
これで、すべてのセッションに対し、Utilを使って操作することができます。ここでは、Util内のsetStyleとsetValueを利用しました。これは、それぞれ第1引数に指定したidの要素を操作する働きを持ちます。setStyleでは、第2引数のスタイルの値を第3引数の値に設定します。setValueはvalueを第2引数の値に変更します。
ここでは全セッションに対し操作を行いましたが、個々のセッションを操作することも可能です。getScriptSessionsByPageで取得したCollectionには、DefaultScriptSessionというクラスのインスタンスとして全セッションが納められています。このgetScriptSessionsByPageのメソッドを呼び出し、Utilと同様に操作することで、個々のセッションを操作することができるのです。