連載
» 2003年03月08日 00時00分 公開

連載 プログラミングASP.NET ―ASP.NETによるWebアプリケーション実践開発講座― :第15回 セッションとビューステート (2/3)

[田口景介,著]

Sessionプロパティ

 ASP.NETのページを記述したaspxファイルの実行を終えて、レスポンスとして送信されるWebページが完成してしまえば、実行時の状態(変数の値)はすべて破棄されてしまうのが基本だが、Sessionプロパティに格納された値だけは別だ。ここに格納された値はレスポンスを生成し終えた後もサーバ上に保存され、次回ポストバックされたときに再び参照できるようになる。もちろん、Sessionプロパティに直接格納された値だけでなく、そのプロパティから参照されている値も破棄されずに保存される。

■HttpSessionStateオブジェクト

 Sessionプロパティは、Pageクラスのメンバとして宣言されたHttpSessionStateオブジェクトである。このプロパティはディクショナリ形式のコレクション・オブジェクトであり、<キー>と<値>のペアを複数登録できる。キーはstring型、値はobject型である。格納する値オブジェクトのデータ型に制限はない。値の登録時には、キー(以下の例では"username")をインデクサに指定して、値を格納する。値の参照時には同じくキーを指定して、ペアの値を取り出す。なお、Sessionプロパティに格納される値はobject型なので、取り出した値は適切にキャストして利用する。

  Session["username"] = "ksk";
  string user = (string) Session["username"];  // キャストが必須

 いったんSessionプロパティに格納された値は、セッションが終了するか、タイムアウトするか、明示的に削除されるまで、何度ラウンド・トリップしても破棄されることはない。

 Sessionプロパティを利用したサンプル・プログラムをリスト15.1に示す。リスト15.1ではSessionプロパティに変数counterの値を保存して、ポストバックするごとにカウントアップされるカウンタを実現している。

<%@ Page Language="C#" %>
<html>
<head>
<script runat="server">
void Page_Load(object sender, EventArgs e) {
  int counter = 0;
  if (IsPostBack) {
    if (Session["counter"] != null) {
      counter = (int)Session["counter"];
      counter++;
    } else {
      counter = 0;
    }
  }
  lcounter.Text = counter.ToString();
  Session["counter"] = counter;
}
</script>
</head>
<body>

<form runat="server">
<p>
<asp:Label id="lcounter" runat="server" />
<asp:Button Text="up" runat="server" />
</p>
</form>

</body>
</html>

リスト15.1 Sessionプロパティ(sample01.aspx)
sample01.aspxのダウンロード(sample01.zip)

図15.2 sample01.aspxの実行結果
sample01.aspxの実行(www.iwebmethod.netのページ)

■セッション管理

 すでに何度も述べているように、ラウンド・トリップを終えるとサーバ上からほとんどの情報は破棄されてしまう。そこでSessionプロパティが用意されているわけだが、このプロパティはセッションに対してプライベートに管理されているため、複数セッションが同時に進行中の場合、サーバ上には複数のSessionインスタンスが存在していることになる。従って、次にポストバックしたとき、どのSessionインスタンスへアクセスすればいいのか、識別するためのセッションIDが必要になる。

 このセッションIDは、通常クッキーに保存される。ASP.NETページへアクセスすると、120bitからなるセッションIDが暗黙的に発行され、例えば以下のようなデータがHTTPヘッダを通して、クライアントへと送信される。

  Set-Cookie: ASP.NET_SessionId=4yxzcq55ce4v1w45liftrf55; path=/

 このクッキーはクライアントのメモリ上に保存されるが、ディスクへは書き込まれないため、ブラウザを閉じてセッションを終了すれば、クライアント上から破棄されてしまう。そうなれば、このセッションIDに対応付けられていたSessionインスタンスへアクセスする手段はなくなり、タイムアウトを待つだけとなる。

 ASP.NETアプリケーションのセッションは、こうしてクッキーを利用して管理されているため、クッキーをブロックしてしまうユーザーの場合、クッキーが保存されないので、ポストバックするたびに異なるセッションIDが発行されてしまい、セッションを継続できなくなってしまう。Sessionプロパティに値を保存しても、次のポストバックを行ったとき、その値を参照できないということだ。例えば、リスト15.1の場合ならば、何度[up]ボタンをクリックしても、カウンタの値は0のままとなる。

 もしこうしたユーザーに対してもセッション管理を行いたければ、クッキーを使わず、代わりにセッションIDをURLに埋め込む方法が提供されている。この方法を使うと、ASP.NETアプリケーションへアクセスしたときに、以下のようにURLがセッションID(この例では“4loltr453qe01sadabumak55”)を含むように置換され、セッション管理が行われる。

オリジナル
  http://localhost/aspnet/sample01.aspx

セッションID込み
  http://localhost/aspnet/(4loltr453qe01sadabumak55)/sample01.aspx

 このクッキーレス・モードを利用したセッション管理を行うには、以下のweb.configファイルをアプリケーション・ルート(仮想ディレクトリとして指定したディレクトリ)に作成するだけでよい。コードの修正は必要ない。

<configuration>
  <system.web>
    <sessionState cookieless="true" />
  </system.web>
</configuration>

リスト15.2 クッキーレス・モードを使用するための設定(web.config)

■セッションのタイムアウト

 すでに解説したとおり、Sessionプロパティに格納された値には有効期限が設定されており、これを過ぎると自動的に破棄されてしまう。この有効期限はデフォルトで20分に設定されているが、サーバ・リソースを節約するためにもっと短い有効期限を設定することもできる。

 Sessionプロパティの有効期限は、クッキーレス・モードの設定と同じく、web.configファイルのsessionState要素で行う。このtimeout属性に分単位で指定した値がセッションの有効期限となる。例えば、リスト15.3に示すweb.configならば、セッションのアイドル状態が10分継続した時点でタイムアウトとなり、セッションが破棄される。

<configuration>
  <system.web>
    <sessionState timeout="10" />
  </system.web>
</configuration>

リスト15.3 セッションの有効期限を10分に設定(web.config)

 なお、タイムアウトしてもセッションIDは再発行されず、同じ値のまま継続して利用されるが、Sessionコレクションは空になるので、どのキーでアクセスしても値はnullとなる。

■ステートサーバ

 通常、セッション情報はASP.NETアプリケーションを実行するワーカー・プロセス(IIS本体ではなく、実際にアプリケーションを処理するプロセス)内部に保存されているが、より高レベルなサービスを提供するために、ステートサーバと呼ばれる、プロセス外にセッション情報を保存する手段が提供されている。

 ステートサーバを利用するメリットは、信頼性の向上にある。ステートサーバはIISから独立したプロセスとして実行されるため、ワーカー・プロセスが誤動作したり、IISを再起動したりしても、ステートサーバに保存されたセッション情報が失われることはない。もちろん、その瞬間にアプリケーションが起動されていたセッションは正しいレスポンスを返すことはできないだろうが、ユーザーからのポストバックを待っていたセッションは、IISさえ正常に戻れば、そのまま何食わぬ顔で処理を継続できる。

 また、IISとステートサーバは、ネットワーク接続さえされていれば、同一マシン上に存在していなくても構わない。従って、Webファーム(クラスタ化されたWebサーバ群)に対して、独立したステートサーバを1台用意する構成を取れば、1台のWebサーバに障害が発生しても、残りのWebサーバがセッションを継続できる(ステートサーバがウイークポイントとなってしまうが)。

 パフォーマンスでは通常のインプロセス・モードに分があるが、信頼性を優先させるならば、ステートサーバ・モードの利用を検討するとよいだろう。

 ステートサーバ・モードを利用するにあたって必要な作業は、ステートサーバを起動し、以下に示すweb.configファイルを用意することだけだ。アプリケーション・コードに修正は必要ない。web.configファイルでは、sessionState要素のmode属性に"StateServer"を、stateConnectionString属性に「tcpip=<ステートサーバ・マシンのIPアドレス>:42424」を設定すればよい。

<configuration>
   <system.web>
    <sessionState mode="StateServer"
      stateConnectionString="tcpip=127.0.0.1:42424" />
   </system.web>
</configuration>

リスト4 ステートサーバ・モードを使用するための設定(web.config)

 ステートサーバは「ASP.NET State Service」の名前でサービスとして登録されているので、サービス・マネージャで起動する。

図15.3 サービス・マネージャにおけるステートサーバの設定画面
サービス・マネージャはコントロール・パネルの[管理ツール]−[サービス]で実行することができる。ステートサーバはWindowsサービスとして動作する。

 なおここでは割愛するが、セッションの情報はSQL Serverによりデータベースで管理することも可能だ。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。