TOP書籍連動> 画面に出力する例
JPSpanを使ってAJAXをしよう!
JPSpanを使ってAJAXをしよう!

第2回:サーバ用のスクリプトの例

著者:Joshua Eichorn   2005/11/9
前のページ  1  2   3  次のページ
画面に出力する例

   次のような動きをするサンプル作成を説明していきます。
  1. テキスト形式の入力ボックスとボタンを配置して、
  2. ボタンをクリックすると、
  3. サーバにテキストが送信され、
  4. サーバから別の文字列を返却され、
  5. innerHTMLを使って、その文字列をdivタグに表示する

表1:サンプルの動き

   この場合も他のAJAXのサンプルと同様、PHPコードとJavaScript・HTMLという2種類の部品に分かれています。リスト2にJPSpanサーバのPHPコードを掲載しました。今回の場合、Exampleクラスではecho_string()メソッドを用意しています(リスト2)。このメソッドでは、数秒間、処理を待機した後、入力データを返します。

1 <?php
2 class Example {
3
4     function foo() {
5          return ‘bar’;
6     }
7 }
8 ?>
リスト2:JPSpanサーバのPHPコード

   クライアント側の処理はすべてJavaScriptで行われます。リスト3にHTMLを掲載しますので上から下に読み進めていきましょう。

<html>
     <head>
          <title>JPSpan echo Example<⁄title>
          <!-- JpSpan のJavaScript クライアントを読み込む -->
          <script type='text⁄javascript' src='server.php?client'>
          <⁄script>
          <script type='text⁄javascript'>
          ⁄⁄ HTML から呼び出される関数
          function echoString(string) {
               remoteExample.echo_string(string);
          }

          ⁄⁄ コールバッククラス
          function exampleCallback() {}
          exampleCallback.prototype.echo_string = function(result) {
          document.getElementById('target').innerHTML += result+
          "<br>";
          }

          ⁄⁄ リモートのプロキシクラス
          var remoteExample = new example(new exampleCallback());
          <⁄script>
     <⁄head>
     <body>
          <input id="source" type="text"><button onclick="echoString(document.getElementById('source').value)">Echo<⁄button>
          <div id="target">
          <⁄div>
     <⁄body>
<⁄html>
リスト3:クライアント側の処理に使用するHTML

   まず、生成されたJavaScriptのクライアントファイルをインクルードします。そうすると、exampleという名前のJavaScriptクラスが作成されます。クラスにはサーバ側のクラスメソッドに対応するメソッドが用意されます。

   次に、ボタンを押すことによって呼び出される関数を記述します。今回の場合は、exampleクラスのecho_string()メソッドを呼び出しています。

   続いてコールバッククラスの定義をします。JPSpanでは、非同期の呼び出しはすべてコールバッククラスで処理されますので、PHPクラス側では、結果を処理するメソッドをコールバックに追加するだけです。今回の場合は、サーバからの結果を追加するecho_string()メソッドを用意しています。

   JavaScriptの最後でJPSpanのプロキシクラスを作成し、コンストラクタにはコールバッククラスのインスタンスを渡します。その後はHTMLが続き、JavaScriptと連携するためのonClickアクションが入っています。

   このサンプルを実行してみましょう。気づいた方がいるかもしれませんが、Echoボタンを立て続けにクリックすると、「[Client_Error][1001] Call inprogress」といった警告メッセージが表示されてしまいます。この原因は、JPSpanプロキシのインスタンスは1度に1回しか呼び出しができないためです。今回の場合、サーバ側の処理に1秒かかる(サーバ側でsleep(1)を呼び出している)ため、立て続けに同時に2つの呼び出しが行われる可能性は高く、その都度エラーになってしまいます。

   この問題の解決にはいくつかの方法があります。1つは、呼び出しが行われている間はボタンをクリックできないようにすることです。あるいは、呼び出しを行うたびに新しいプロキシのインスタンスを作成する方法もあります。また他にも、オブジェクトをプールしておくことも考えられます。

   オブジェクトプールを使って、呼び出しが行われるごとにプロキシオブジェクトを作成することにより、JavaScriptオブジェクトの作成量が少なくなります。そうするとメモリリークを防ぐ可能性が高まりますし、プロセス全体を制御しやすくなります。

   そこで今回、私は簡単なオブジェクトプール(リスト4)を作成しました。待機状態のプロキシオブジェクトがあった場合はそれを使い、なかった場合は新しいオブジェクトを作成します。使用するプロキシオブジェクトの数も簡単に制限できますので、ユーザが大量の呼び出しを行う時でも対応することができます。

1 ⁄⁄ 必要に応じて自動的に作成されるオブジェクトプール
2 function objectPool() {
3      this.pool = new Array();
4      this.avail = new Array();
5 }
6
7 ⁄⁄ このメソッドをオーバーライドして
8 ⁄⁄ JPSpan のプロキシインスタンスを作成する
9 objectPool.prototype.createObject = function() {
10      return new Object();
11 }
12
13 ⁄⁄ プールから新しいオブジェクトを取り出す
14 objectPool.prototype.getObject = function() {
15      ⁄⁄ 必要に応じて、オブジェクトを作成する
16      if (this.avail.length == 0) {
17           var o = this.createObject();
18           o.poolId = this.pool.length;
19           this.pool.push(o);
20           this.avail.push(o.poolId);
21      }
22
23      var poolId = this.avail.pop();
24      return this.pool[poolId];
25 }
26
27 ⁄⁄ オブジェクトをプールに返す
28 objectPool.prototype.returnObject = function(poolId) {
29      this.avail.push(poolId);
30 }
リスト4:オブジェクトプール

   このオブジェクトプール機構を加えたコードがリスト5です。オブジェクトプール機構を追加するのに、あまり変更の必要がないことに気づくでしょう。createObject()メソッドをオーバーライドし、get_object()メソッドを使って呼び出しを行い、終了時にreturnObject()メソッドを呼び出すようにしました。ただし、これらの呼び出しが想定外の順番で行われる可能性があるため、それを制御するためのJavaScriptコードを多少含んでいます。

1 function echoString(string) {
2 remotePool.getObject().echo_string(string);
3 }
4
5 ⁄⁄ コールバックを呼び出す
6 function exampleCallback() {}
7 exampleCallback.prototype.echo_string = function(result) {
8      document.getElementById('target').innerHTML +=
9           result+"<br>";
10      remotePool.returnObject(this.parent.poolId);
11 }
12
13 ⁄⁄ JPSpan のプロキシクラスをプールする
14 var remotePool = new objectPool();
15 remotePool.createObject = function() {
16      var callback = new exampleCallback();
17      var remote = new example(callback);
18      callback.parent = remote;
19      return remote;
20 }

リスト5:オブジェクトプール機構を加えたコード

前のページ  1  2   3  次のページ


Joshua Eichorn
著者プロフィール
Joshua Eichorn
Joshua Eichornは、PHPを使ったWebサイトを7年間制作してきました。彼は、非常に有名なPHPのドキュメーションツールであるphpDocumentorの制作者です。また彼は、アリゾナ州立大学のScience in Computer InformationSystems学部の学士号をとっています。
彼はUversa社のシニア設計者として、AJAXをUversa社のアプリケーションに追加する作業を行っています。現在、アリゾナ州フェニックスに住んでいます。


INDEX
第2回:サーバ用のスクリプトの例
  JPSpanサーバ
画面に出力する例
  スクロールするテーブル