ナッキーの「Turbo Delphiはじめて奮戦記」 - 第21回 占いプログラムでWebサービス - サーバー編

By: Hitoshi Fujii

Abstract: 以前、血液型占いのプログラムを作りましたが、それをより多くの方に使っていただきましょう。可変の情報や機能をインターネットの技術を使って提供するWebサービスにしてみます。

Hide image
nacky75

ナッキー

「第5回 占いプログラムでレイアウトをマスター」で作った血液型占いはラッキーアイテムが5種類しかないんですよね。友達に配布したんですが、すぐに飽きられちゃいました。

 

Hide image
takahashi75b

高橋先生

今回からは、新しいことを勉強するよ。占いプログラムにも、いろいろ工夫してバリエーションを持たせてみよう。


    インターネットインフォメーションサービス(IIS)のインストール

「第5回 占いプログラムでレイアウトをマスター」で作った血液型占いを友達に送ったんです。最初は面白がってくれたけど、ラッキーアイテムが限られていて、すぐに飽きられちゃいました。ラッキーアイテムを変更したり、ラッキーアイテムだけじゃなくて、ラッキーナンバーを表示したりするにはどうしたらいいのかな?教えて、高橋先生!

高橋先生:じゃあ、まず配布したプログラムを変更する方法を、思いつきでいいから挙げてみて。

ナッキー:う~ん。普通に作ったプログラムを加工して配布しなおす、とか?

高橋先生:それでは、もし毎日変更したらどうだろう?毎日プログラムに手を加えて配布するかな?使う人も毎日プログラムを入れ替えてくれるだろうか?

Hide image
dt21_fig01

図01 プログラムの更新

ナッキー:それじゃあ、ラッキーアイテムだけ別のファイルにして配布するのはどうですか?

高橋先生:やっぱり配布するの?ファイルの入れ替えの作業をお友達に頼らない方法はないかな?

ナッキー:え~。そうだ!前回やったデータベースはどうですか?ラッキーアイテムをデータベースに入れておいて、友達のプログラムはデータベースにアクセスして新しいラッキーアイテムをゲットするんです。

高橋先生:お!一歩前進したね。データベースにお友達がアクセスできるようにセットアップしなくちゃならないけど、そういう方向でもうちょっと考えてみて。ラッキーアイテムをラッキーナンバーに変えるとか、ランダムな値ではない結果を渡すといった大きな変更の時には、データベースを使っても再配布が必要になるよ。

Hide image
dt21_fig02

図02 データベースプログラム

ナッキー:そうなんですかぁ。私はインターネットにある、占いサイトみたいに生年月日を入力すると占いの内容が画面に表示されたり、新しいコーナーを追加したりできるといいなと思ってるんだけなんですけど。普通のプログラムではそういうの難しいんですね。

高橋先生:難しすぎるっていうことはないよ。今言ったインターネットの技術を使って、プログラムを作成することもできるんだよ。それは「Webアプリケーション」や「Webサービス」と呼ばれる技術。Webアプリケーションは、Webブラウザを使って動作するアプリケーション。Webブラウザからサーバーに要求を出して、サーバーのプログラムがWebページを作成して返すんだ。このとき、WebアプリケーションとクライアントのWebブラウザとのやり取りには「HTTP」というプロトコルを使っている。プロトコルはネットワークを通じて情報をやり取りするときの約束。

Hide image
dt21_fig03

図03 Webアプリケーション

Webアプリケーションを作るには、クライアントの要求に対してWebサーバー上で動くプログラムを作らなくてはいけない。サーバー上のプログラムを動かす仕組みにCGI(Common Gateway Interface)がある。CGIの仕組みを使ってWebサーバーの上で動くプログラムのことをCGIプログラムという。

ナッキー:プログラムで新しく、Webページを作るんですね。

高橋先生:Webアプリケーションの場合は、クライアントのブラウザの機能を使って情報を表示するけれど、Webサービスは結果を表す機能をブラウザに限定していない。Webサービスを使うと、SOAPというプロトコルを使って、いろんな機能をインターネット経由で呼び出せるようになるんだ。

Hide image
dt21_fig04

図04 Webサービス

ナッキー:へえ、便利なんですね。

高橋先生:ここではCGIを使った占いWebサービスを作ってみよう。これなら、プログラムがサーバーにあるので、変更があるときはサーバーのプログラムを書き直すだけでいい。お友達はいつもどおり、ナッキーのWebサーバーにアクセスするだけだ。

ナッキー:でも、Webサーバーのプログラムなんて、自宅のパソコンで作れるんですかぁ?

高橋先生:心配ないよ、手軽なツールがWindowsにあるからそれを使ってみよう。ほかにも無償のツールが出回っているけれど、ここではWindowsのツールInternet Information Services (IIS)を使った例で紹介するよ。

ナッキー:はーい。あれ?ウチのパソコンには、そのインターネットなんとかは入っていないみたいです。

高橋先生:デフォルトでは入っていないことがあるから、インストールからはじめてみよう。Windowsの入っているCD-ROMを手元に用意してからはじめよう。手順に従って挑戦してみて。


よーし、インストールにはだいぶ慣れてきたから、きっと大丈夫よ。まずは、WindowsのCD-ROMをドライブにセットしてっと。インストール用の画面が表示されますが、今回はコントロールパネルから設定する方法を紹介しますので、閉じてしまいます。スタートメニューから[コントロールパネル(C)]を選択します。

Hide image
05コントロールパネル

図05 コントロールパネル

一覧から、「プログラムの追加と削除」を選択します。画面の左側から[Windowsコンポーネントーの追加と削除(A)]をクリックします。

Hide image
06プログラムの追加と削除

図06 プログラムの追加と削除

次に表示されるコンポーネントウィザードでは、追加する機能をクリックして選ぶことができます。

Hide image
07コンポーネントウィザード

図07 コンポーネントウィザード

一覧から「インターネット インフォメーション サービス(IIS)」をクリックして「レ点」をつけます。確認して、[次へ(N)]ボタンをクリックします。

Hide image
08コンポーネントウィザード

図08 コンポーネントウィザードの完了

しばらくすると画面が切り替わって、コンポーネントウィザードが完了します。完了の画面が表示できたら[完了]ボタンをクリックします。これで、インストールは終わりです。CD-ROMを取り出してかまいません。

    IISを停止する

高橋先生:IISをインストールしたパソコンはインターネットを経由して接続できるようになるんだ。

ナッキー:当たり前ですよ、インターネットはいつでも接続できますよね。

高橋先生:ナッキーのパソコンから、インターネットに接続するのではなくて、ほかのパソコンから、インターネットを経由して接続できるようになるんだ。

ナッキー:えっ!じゃあ、データとか危険なんじゃないですか?

高橋先生:まあ、まあ。公開しているのは特定のフォルダだから、それほど深刻な問題として捉えなくてもいいよ。でも、必要のないときは公開しないほうがいいね。起動確認のついでにプログラムのテストまで機能しないよう、設定しよう。

ナッキー:わぁ、ドキドキしましたよ。簡単にほかのパソコンから接続されないように設定しておきます。


それじゃあ、IIS管理用のツールを起動してみます。まず、スタートメニューから[コントロールパネル(C)]をクリックします。コントロールパネルが表示されたら「管理ツール」アイコンをダブルクリックします。

Hide image
09管理ツール

図09 管理ツール

一覧に「インターネット インフォメーション サービス」があることを確認します。表示されていなければ、インストールがうまくできなかったかもしれません。もう一度インストールしなおしてみてください。

IISを起動するたびに、ここまでの操作をするのが面倒な場合は、デスクトップにショートカットを作っておきます。シートカットを作るには、はじめにデスクトップの一部が表示できるように、ほかのウインドウを移動しておきます。次にマウスの右ボタンを使って、管理ツールから「インターネット インフォメーション サービス」をデスクトップが表示されている部分に、ドラッグします。表示されるメニューから[ショートカットをここに作成(S)]をクリックします。

作成したショートカットか、管理ツールから「インターネット インフォメーション サービス」のアイコンをダブルクリックします。なんだか、ファイル管理ツールみたいな画面ですね。

起動が確認できたら、IISの機能を止めておきます。画面の左側はフォルダの名称です。「インターネット インフォメーション サービス」の下に、ネットワーク上のコンピューターの名前と「(ローカルコンピュータ)」が表示されています。先頭の「+」マークをクリックすると、「Webサイト」、さらに「+」マークをクリックすると、「既定のWebサイト」が表示されます。「既定のWebサイト」を選択して、ツールバーの[項目の停止](■)ボタンをクリックします。

Hide image
10インターネットインフォメ

図10 インターネットインフォメーションサービス

これでこのパソコンはインターネット上に公開しなくなりました。

    Webサーバーのプログラムを作る

あー、これでほっとしました。次はいよいよプログラミングですね。でも、何から手をつけていいやら。

高橋先生:IISを止めておけば安心だね。次はWebサーバーのプログラムを作成しよう。作り方はオブジェクトリポジトリでテンプレートを使えば簡単だよ。

ナッキー:オブジェクトリポジトリって、なんでしたっけ?

高橋先生:サブフォームを扱ったとき、使ったよ。バージョン情報フォームを作るときに、フォームの雛形が入ったテンプレートを利用した。同じようにプロジェクトの作成のときにテンプレートを使おう。

ナッキー:そういえば、少し加工しただけでフォームができちゃいましたよね。プロジェクトでも同じように、ちょっと加工するだけで使えるようになるといいな。


それでは、Turbo Delphiを起動して、プロジェクトを新規で作成します。起動できたら、メニューバーの「ファイル(F)|新規作成(N)|その他(O)...」を選択します。画面左側の「項目カテゴリ(A):」欄で、「Delphiプロジェクト」の[+]をクリックして展開します。一覧から「WebServices」をクリックして、右側に表示されるアイコンから「SOAPサーバーアプリケーション」を選択します。設定によっては表示されるアイコンの数が異なるかもしれません。

Hide image
11オブジェクトリポジトリ

図11 オブジェクトリポジトリ

選択を確認して、[OK]ボタンをクリックします。そうすると「WWWサーバーアプリケーションの形式を以下から選んでください」というメッセージが表示されます。一覧から「CGI実行形式(C)」を選択して、[OK]ボタンをクリックします。

Hide image
12SOAPサーバーの新規作成

図12 SOAPサーバーの新規作成

プロジェクトが作成できたら、「SOAPモジュールのためのインターフェースを作成しますか?」というメッセージが表示されますので、[はい(Y)]ボタンをクリックします。

Hide image
13インターフェースを作成し

図13 インターフェースを作成しますか?

今度は「Webサービスの新規追加」の画面が表示されます。ここでは、「サービス名(N)」に「Uranai」、「ユニット名(U)」にも「Uranai」、「サンプルメソッドの生成(S)」をクリックしてチェックをつけます。

Hide image
14Webサービスの新規作成

図14 Webサービスの新規作成

入力できたら、[OK]ボタンをクリックします。すると、コードエディタに画面が切り替わって、コメントの入ったコードがいくつか表示されます。画面右上のプロジェクトマネージャには通常の「Project1.exe」や、「Unit1.pas」のほかに「UranaiImpl.pas」や「UranaiIntf.pas」ファイルが作成されます。自動的に作成されるプロジェクト名や、ユニット名の末尾の数字は、「Project2」や「Unit3」のように異なっていてもかまわないんですって。

Hide image
15プロジェクトマネージャー

図15 プロジェクトマネージャ

できたら名前をつけて保存しましょう。ツールバーの[すべて保存]ボタンをクリックします。「UranaiIntf.pas」と「UranaiImpl.pas」はそのまま、Unit1のユニット名は「UranaiServerUnit」、プロジェクト名は「UranaiServer」とします。

    占う機能を追加する

なんだか、いっぱいファイルができましたね。これってどんなユニットなんだろう?

高橋先生:おおざっぱに紹介すると、

  • UranaiServerUnit.pas 通信のためのユニット
  • UranaiIntf.pas インターフェース(クライアントとやり取りする)ユニット
  • UranaiImpl.pas 実装(機能が入っている)ユニット

のように3つのユニットで構成されている。これだけで、サーバー側はほとんど完成。あとは機能の部分を追加するだけだよ。

ナッキー:その、機能を追加するところが大変なんじゃないですか?

高橋先生:今回は占いプログラムの機能をサーバー側とクライアント側に分けてみたい。元々の占いプログラムが提供しているのは、ボタンをクリックすると選んだボタンに合わせて占い結果をメッセージボックスに表示するというものだったね。そのうちの占い結果を生成する部分、「ShowItem」関数をちょっと加工してサーバー側にやらせよう。コードは占いプログラムからコピーすれば簡単だ。それから、関数の戻り値として占いの内容を渡すようにしよう。

ナッキー:戻り値ってどうやって渡すんでしたっけ?

高橋先生:しばらく関数はやっていなかったから忘れちゃったかな?「Result」っていう特殊な変数に値を代入すれば戻り値になるよ。

ナッキー:思い出しました。コードはコピーするって言ってましたけれど、違うプロジェクトのコードをコピーするのは、なんだか面倒ですね。Webサービスのプログラムを閉じて、占いプログラムを開いてコピーして、もう一度Webサービスのプログラムを開いて、貼り付けるんですよね。わーこんがらがるぅ。

高橋先生:しょうがないな。では、メモ帳を使ってコピーしよう。Delphiで作成したユニットは文字でできているからメモ帳でも読めるんだ。

ナッキー:どこに貼り付けたらいいんですか?

高橋先生:Webサービスのプログラムに新しく関数を作成しよう。新しく作る関数の定義はインターフェースのUranaiIntfユニットにも、実装プログラムのUranaiImplユニットにも必要なんだ。関数のコードはUranaiImplユニットだけに記述すればいよ。関数のパラメータには血液型を示すInteger型の値、戻り値は占い結果の文章を渡すのでstring型を使う。末尾につける「stdcall」は手続きや関数を呼び出す規約で、パラメータの呼び出しの順番を決めたりしている。どちらのユニットにも同じ定義でいいよ。

function getUranaiMessage(Blood: Integer): string; stdcall;

定義する場所はUranaiIntfユニットもUranaiImplユニットもInterface部のType節。functionの定義が集まった部分があるから、下に追加しよう。


では、先にUranaiIntfユニットの関数の定義から設定します。プロジェクトマネージャで「UranaiIntf.pas」をダブルクリックして、表示されたコードエディタでType節を探します。見つかったら、「echoDouble」関数と「end;」の間に空白行を挿入して、太字部分を追加します。

type

  TEnumTest = (etNone, etAFew, etSome, etAlot);

  TDoubleArray = array of Double;
  (中略)
    function echoEnum(const Value: TEnumTest): TEnumTest; stdcall;
    function echoDoubleArray(const Value: TDoubleArray): TDoubleArray; stdcall;
    function echoMyEmployee(const Value: TMyEmployee): TMyEmployee; stdcall;
    function echoDouble(const Value: Double): Double; stdcall;
    function getUranaiMessage(Blood: Integer): string; stdcall;
  end;

入力できたら、今度はUranaiImplユニットの関数を定義します。プロジェクトマネージャで「UranaiImpl.pas」をダブルクリックします。コードエディタのType節の「echoDouble」関数と「end;」の間に空白行を挿入して、太字部分を追加します。

type

  { TUranai }
  TUranai = class(TInvokableClass, IUranai)
  public
    function echoEnum(const Value: TEnumTest): TEnumTest; stdcall;
    function echoDoubleArray(const Value: TDoubleArray): TDoubleArray; stdcall;
    function echoMyEmployee(const Value: TMyEmployee): TMyEmployee; stdcall;
    function echoDouble(const Value: Double): Double; stdcall;
    function getUranaiMessage(Blood: Integer): string; stdcall;
  end;

UranaiImplユニットには、そのまま実装部も記述します。実装部を作成するためのショートカットキーがあるんですって。新しく作成した「getUranaiMessage」の行末にカーソルを移動して、「Ctrl+Shift+C」を押します。そうすると以下のようなコードが自動的に作成されます。設定によっては表示されないかもしれません。その場合はそれぞれ入力して作成します。

function TUranai.getUranaiMessage(Blood: Integer): string;
begin

end;

関数の外枠が作成できたら、中身は、第5回で作成した占いの処理をコピーしてきます。えーっと、占いプログラムは何処に保存したんだっけ?

Windowsの「マイ コンピューター」か「エクスプローラー」を起動して占いプログラムのコードが入ったファイル「FormFortune.pas」ファイルを探します。特に保存先を指定していない場合は、「My Documents」の「Borland Studio Projects」フォルダに入っています。見つかったらマウスの右ボタンでクリックして、サブメニューから[プログラムから開く(H)|Notepad]を選択します。

Hide image
16メモ帳で開く

図16 メモ帳で開く

コピーするのは「ShowItem」の関数の部分のvar節から「ShowMessage」の部分までです。太字部分をコピーします。

procedure ShowItem(Blood : Integer);
var
  Blood_Type : string;
  Lucky_No : Integer;
  Lucky_Item : string;
begin
  case Blood of
    1 : Blood_Type := 'A';
    2 : Blood_Type := 'B';
    3 : Blood_Type := 'O';
    4 : Blood_Type := 'AB';
  end;

  Lucky_No := Random(5);
  case Lucky_No of
    0 : Lucky_Item := '携帯電話';
    1 : Lucky_Item := '手紙';
    2 : Lucky_Item := '';
    3 : Lucky_Item := 'デジカメ';
    4 : Lucky_Item := 'チョコレート♪';
  end;

  ShowMessage(Blood_Type + 'のあなた、ラッキーアイテムは' + Lucky_Item);
end;

コピーできたら、Turbo Delphiの画面に戻ります。UranaiImplユニットに作成したgetUranaiMessage関数にコピーした内容を貼り付けます。「begin」が重複しているかもしれません。削除し忘れないように気をつけなくっちゃ。最後の1行の「ShowMessage」のパラメータの内容を「Result」変数に代入するように書き換えます。太字部分を参考にして入力します。

function TUranai.getUranaiMessage(Blood: Integer): string;
begin  //削除する
var
  Blood_Type : string;
  Lucky_No : Integer;
  Lucky_Item : string;
begin
  case Blood of
    1 : Blood_Type := 'A';
    2 : Blood_Type := 'B';
    3 : Blood_Type := 'O';
    4 : Blood_Type := 'AB';
  end;

  Lucky_No := Random(5);
  case Lucky_No of
    0 : Lucky_Item := '携帯電話';
    1 : Lucky_Item := '手紙';
    2 : Lucky_Item := '';
    3 : Lucky_Item := 'デジカメ';
    4 : Lucky_Item := 'チョコレート♪';
  end;

  Result := Blood_Type + 'のあなた、ラッキーアイテムは' + Lucky_Item;
end;

これで完成!うまく貼り付けられたらメモ帳は保存しないで終了します。なんだか、よくわからないうちにできちゃいましたね。保存して実行してみます。ツールバーの[すべて保存]ボタンをクリックして保存できたら[実行]ボタンで実行します。コンパイルも通ったし、これで動くのね。あれ?元のコードエディタに戻っちゃいました。エラーとか出なかったのにぃ@@。教えて、高橋先生!

高橋先生:エラーが出なければ、OKなんだ。大丈夫だよ。Webサーバーのプログラムはクライアントの要求で動くのが役目だから、これだけ実行しても目に見える事は何もおこらないよ。エラーが出ないで終了できればいいんだ。

ナッキー:これで、いいんですか。なーんだ、何か失敗しちゃったのかと思いましたよ。こんな結果になるんなら早めに教えてくださいよ。

高橋先生:今回はここまで。次回は実行すると目に見える方を作っていこう。

ナッキー:目に見えるものがないので、なんだか達成感が薄いなぁ。その分次回に期待します。


ナッキーの「Turbo Delphiはじめて奮戦記」

Prev | Next | Index


Server Response from: ETNASC01