2006 年 9 月 7 日 23 時 51 分

状態遷移


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


一般的に、コンピュータシステムを利用する際は、
「ログイン」⇒「使用」⇒「ログアウト」の手順を踏む。

このようなシステムは、状態(ステート)を持つ。
例えば「ログイン前」や「ログイン中」などが状態だ。

状態と密接に関係しているものに、画面表示がある。
例えば、ログイン前の状態なら、
ログイン用の画面が表示され、
ログイン中の状態なら、メニューなどが表示される。
画面の表示は、状態によって異なるのだ。

また、状態は操作によって変化する。
例えば、ログイン用の画面で適切な認証情報を入力し、
「ログイン」と書かれたボタンを押せば、
「ログイン中」か「ログイン失敗」の状態に変化し、
状態に即した画面が表示されるはずだ。

状態遷移は、システムに必要不可欠なものなのである。
では、WWW で同様の仕組みを構築する場合はどうなるか。

WWW は、Web ブラウザなどのユーザエージェントと
Web サーバが協調して動作するため、
状態遷移の仕組みを導入するには、
その両側で状態を共有する必要がある。

しかしながら、HTTP においては、
Web サーバは、Web ブラウザの要求した、
リクエストやヘッダの内容だけを基準として処理をし、
以前に通信があったことなどは覚えていない。

つまり、通信はそれぞれ独立しており、
HTTP 自身は状態を持たないことになる。
となると、状態遷移を実現するためには、
CGI などのプログラムで処理する必要がある。

ただ、CGI は、サーバ側の仕組みであるため、
Web ブラウザの動作を変えることはできない。
そのため、状態の受け渡しは、
HTTP で規格化されている方法で行う必要がある。

Web ブラウザで可能な操作は、
ハイパーリンクによって別のページに移動することと、
ボタンなどを含むフォームの内容を送信することである。

そのため、CGI で状態管理をするためには、
ハイパーリンクの URL のクエリパラメータや、
フォームの隠し項目に状態を表す値をを格納しておく。

<a href="menu.cgi?status=xxxx">メニューへ</a>

<form action="add-comment.cgi" method="post">
    <input type="hidden" name="status" value="xxxx" />
    <input type="text" name="title" />
    <textarea name="message" cols="60" rows="4">
        (コメントを入力します)
    </textarea>
</form>

例えば、上記のようにすれば、Web ブラウザを操作して、
別のページ(画面)に移動する際に、
URL やフォームを通じて status パラメータが、
Web サーバ側に渡されるようになるのだ。

確かにこれでうまくはいく。

しかし、この作業は非常に手間が掛かる。
大規模なシステムでは、状態を管理するためだけに、
ハイパーリンクやフォームのパラメータを変えるのは大変だ。

例えば、mixi を例にして考えてみよう。
自分のトップページの http://mixi.jp/home.pl には、
非常に数多いハイパーリンクがある。

mixi はユーザ認証が必要なので、
「ユーザ XXX としてログイン中」という、
状態情報をどこかに持っているはずだ。

もし、この情報を URL に持たせて維持する場合、
トップページにある数多いハイパーリンクの
その全てに状態パラメータを埋め込む必要がある。
これはかなり骨の折れる作業となる。

さて、実際の mixi のページのソースを見てみよう。
ハイパーリンクにはクエリパラメータ等は含まれていない。

また、http://mixi.jp という URL にアクセスすると、
ログインページに遷移するが、一度ログインに成功すると、
同じ URL なのにも関わらず、自分のページが表示される。

さらに、「次回から自動的にログイン」にしておけば、
一切ログイン情報の入力なしに、自分のページが表示される。

利用者が Web ブラウザを全て閉じたとしても、
さらにはコンピュータを再起動したとしてもだ。

上記の方法による状態管理では、
「自動的にログオン」などは絶対に実現できない。
つまり、何か別の方法で状態の管理が行われているのだ。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.