この特集のトップページへ
Chapter 8:プレゼンテーション層の構築

8.2.2 アプリケーションとセッション
Applicationオブジェクトを使ったWebアプリケーションのデータ保存
 ところで,ASPにはSessionオブジェクトと似たようなオブジェクトとして,Applicationオブジェクトが提供されている。Applicationオブジェクトは,仮想ディレクトリ内に用意された値を保存することができるコレクションを提供する。


One Point!ApplicationオブジェクトもSessionオブジェクトと同様に,仮想ディレクトリ単位で用意される。別々の仮想ディレクトリに配置されたASPファイルでは,異なるApplicationオブジェクトが使われる。

 Applicationオブジェクトの使い方は,Sessionオブジェクトとよく似ている。ApplicationオブジェクトにはSessionオブジェクトと同様にContentsコレクションが実装されており,任意の値に任意の名前を付けてデータを保存することができる。


<% Application.Contents("識別子") =  %>

One Point!ApplicationオブジェクトとSessionオブジェクトは何の関連性ももたない。よって,ApplicationオブジェクトとSessionオブジェクトに対し,同じ識別子を使って値を保存したとしても,それらは別物として扱われる。

 ApplicationオブジェクトもSessionオブジェクトと同様,Contentsコレクションを省略し,次のように表記することもできる。


<% Application("識別子") =  %>

 ApplicationオブジェクトとSessionオブジェクトの違いは,Sessionオブジェクトがクライアントごとに保存領域を用意するのに対し,Applicationオブジェクトは仮想ディレクトリごとに共有する領域を作るという点である。つまり,Applicationオブジェクトには,どのクライアントからも値を保存することができ,また,どのクライアントからも値を参照することができるということを意味する。

 たとえば,Applicationオブジェクトを利用し,List 8-28のようなスクリプトを実装すれば,簡易チャットシステムができあがる。

 List 8-28は,Fig.8-50のような構成のWebアプリケーションとなっている。具体的には,[メッセージをどうぞ]の右側にあるテキストフィールド(MSGテキストフィールド)に発言を入力して[送信]ボタンを押すと,その発言がページの後ろに追加されてゆく。[リロード]ボタンは,単に同じページを再度表示するだけの機能である。

Fig.8-50 List 8-28の実行結果(適当に発言をしたあとのもの。[送信]ボタンを押すたびに発言が後ろに加わってゆく)
fig8_50

 List 8-28の5〜10行目では,[送信]ボタンが押されたときにMSGテキストフィールドに入力されたメッセージをApplicationオブジェクトに登録するという処理をしている。

 List 8-28では,その時点で登録されている発言数をMAXMESSAGEという名前で,登録されているそれぞれの発言をMSG0MSG1,……,MSGnn=MAXMESSAGE - 1)という名前で,それぞれApplicationオブジェクトに記録するようになっている。

 6行目にあるように,発言を登録するときには,まずMAXMESSAGEという名前に結び付けられた値をApplicationオブジェクトから取得し,それを変数maxMessageに格納する。そして7行目で,ユーザーが入力した発言をApplicationオブジェクトに登録する。


maxMessage = Application("MAXMESSAGE")
Application("MSG" & CLng(maxMessage)) = _
  Request("MSG")

 最初の発言であれば,Application("MAXMESSAGE")の値がEMPTY値となるので,maxMessage変数もEMPTY値となるが,CLng(maxMessage)としたときには0と評価される。結局,Request("MSG")の値(これはユーザーがMSGテキストフィールドに入力した発言の文字列である)は“MSG0”という名前でApplicationオブジェクトに登録されることになる。

 そして8行目ではmaxMessage変数の値をインクリメントし,9行目でmaxMessage変数の値をMAXMESSAGEという名前でApplicationオブジェクトに格納する。これにより,Application("MAXMESSAGE")の値がインクリメントされ,次に実行されたときには,Application("MAXMESSAGE")の値が,1,2,……と順に増えることになる。よって次回以降,7行目の処理では,ユーザーが発言したメッセージ(Request("MSG"))が,Application("MSG1")Application("MSG2"),……というコレクションに対して次々と格納されてゆくことになる。

 Applicationオブジェクトに登録された発言は,18〜20行目で表示している。ここでは,Application("MAXMESSAGE")の値を参照し,その数だけループ処理をしている。ループ処理によって,Application("MSG0")Application("MSG1"),……のように発言を順に取り出し,その結果をResponse.Writeメソッドを使ってユーザーに出力しているだけである。特に説明はいらないだろう。

 Applicationオブジェクトは,仮想ディレクトリ単位で用意される共通の記録領域である。よって,Fig.8-51に示すように,アクセスしたすべてのクライアントは同じ発言内容を参照することになる。

Fig.8-51 List 8-28の動作
fig8_51

 ところで,Applicationオブジェクトは仮想ディレクトリ内のすべてのWebページからアクセスされるから,同時アクセスの排他制御の問題が重要になる。つまり,あるクライアントがApplicationオブジェクトの値を書き換えているあいだに,別のクライアントがさらに値を上書きする可能性が否定できない。

 そこで用意されているのが,ApplicationオブジェクトのLockメソッドとUnlockメソッドである。Application.Lockメソッドが呼び出されると,その時点でApplicationオブジェクトはロックされる。同じ仮想ディレクトリ内のほかのASPファイルからApplicationオブジェクトにアクセスしようとすると,その時点で処理は一時停止する。Application.Lockメソッドを呼び出してロックした場合,(1)Application.Unlockメソッドを呼び出す,(2)Application.Lockメソッドを呼び出したASPファイルの実行が終了する(タイムアウトによる強制終了も含む),のいずれかの場合に,ロックが解除される。解除された時点で,Applicationオブジェクトにアクセスしようとして一時停止状態にあったASPファイルの実行が再開される。

 つまり,Application.Lockメソッドの呼び出しとApplication.Unlockメソッドの呼び出しで囲まれた部分は,ほかのASPファイルによってApplicationオブジェクトの値を変更されてしまうことがなくなる。

 List 8-28では,5行目でApplication.Lockメソッドを呼び出し,10行目でApplication.Unlockメソッドを呼び出している。よって,6〜9行目の処理中は,ほかのASPファイルの処理によってApplicationオブジェクトが変更されることはない。

 Applicationオブジェクトを使う場合,ロック機構を考えることは重要である。たとえば,もしList 8-28において5行目のApplication.Lockメソッドの呼び出しと10行目のApplication.Unlockメソッドの呼び出しを省いてしまうと,Fig.8-52に示すような微妙なタイミングで2つのクライアントから同時に呼び出しが発生すると,片方の発言がもう片方の発言を上書きしてしまうことになる。

Fig.8-52 ロックをかけない場合
fig8_52

 ところで,Applicationオブジェクトに保存した情報は,永続的なものではない。IISが終了したときには破棄されてしまうし,作為的に管理者が破棄することもできる。作為的に破棄するには,仮想ディレクトリのプロパティページで[アンロード]ボタンを押せばよい(Fig.8-53)。

Fig.8-53 アプリケーションのアンロード
fig8_53

 [アンロード]ボタンを押したときには,Fig.8-54に示す確認メッセージが表示され,[はい]ボタンを押すとApplicationオブジェクトが破棄される。このとき,高速化のためにスクリプトエンジンによって読み込まれていたASPファイルのキャッシュも破棄される。スクリプトエンジンによるキャッシュとは,[アプリケーションの構成]ダイアログボックスの[アプリケーションのマッピング]ページ(Fig.8-13)に存在する[ISAPIアプリケーションをキャッシュする]にチェックが付いている場合に実行されるキャッシュ処理のことである。

Fig.8-54 アンロードの確認
fig8_54

 Applicationオブジェクトは,破棄される可能性のある一時的な領域にすぎないため,永続的な情報を保存するのには向かない。永続的な情報は,ファイルシステムやリレーショナルデータベースに保存すべきである。一般にApplicationオブジェクトは,全クライアント間で共有の一時情報を保存したり,今回示したチャットのサンプルのようにクライアント間で情報をやり取りしたりしたい場合などに用いられる。

Prev 26/43 Next