• D言語によるWebアプリの実装 その1

    2011年10月25日 00時20分
    最近あまりプログラムを書いていないのでネタがありません。
    とはいえ、何日も更新が無いというのはなんとかしたいものです。


    そこで、DによるWebアプリ実装についての記事を
    細かく刻んで小出しし、乗り切ってみたいと思います。

    ちなみに何故Webアプリかと言うと、
    何回か実装していてわりと内容がまとまっているからです。
    (実はこのブログもDによるWebアプリの実装になっています。)


    この記事ではシンプルな掲示板の作成を目指したいと思います。



    一口にWebアプリといっても色々と実装方法がありますが、
    今回はFastCGIを使用して実装します。
    それと、FastCGI用の自家製フレームワークがありますので併せて使用します。


    FastCGIを選んだのは、せっかくDで書くなら実行速度が速いといいなぁという理由です。


    環境構築

    FastCGIを使いますので、次の2つが必要になります。
    1. FastCGIライブラリ
    2. FastCGI実行環境

    また、Dを使いますのでdmdも必要です。


    環境構築方法は話の本筋ではありませんが、
    「Hello work!!」出すだけだと内容が薄いので、
    CentOS 6.0(x64)上に構築する場合を例として簡単に書いておきます。

    開発環境として、手間がかからず動けば良いという観点の方法ですので、
    実際に構築する場合は色々調整してください。


    FastCGIライブラリのインストール

    CentOS 6.0のMinimalインストールは本当にMinimalだったので
    ビルドツール等を色々入れます。
    # yum -y install gcc
    # yum -y install make
    # yum -y install patch
    # yum -y install wget


    FastCGIサイトからソースをダウンロードして解凍します。
    # wget http://www.fastcgi.com/dist/fcgi.tar.gz
    # tar xzvf fcgi-2.4.0.tar.gz


    GCCのバージョンアップのためかと思いますが、
    EOFマクロがエラーを出すようなので、パッチを当てます。
    (stdio.hのincludeを足すだけです。)
    # cd fcgi-2.4.0/libfcgi/
    # patch -p0 < ../../fcgi-2.4.0-gcc4.patch


    パッチの内容は次の通りです。
    --- fcgio_old.cpp   2002-02-25 05:12:22.000000000 +0900
    +++ fcgio.cpp   2011-10-21 16:26:18.039072131 +0900
    @@ -22,6 +22,7 @@
     #define DLLAPI  __declspec(dllexport)
     #endif
    
    +#include <stdio.h>
     #include <limits.h>
     #include "fcgio.h"


    後はビルドしてインストールします
    # cd ..
    # ./configure
    # make
    # make check
    # make install



    FastCGI実行環境のインストール

    WebサーバはApacheを使います
    # yum -y install httpd


    mod_fcgidのビルドのためにApache開発環境をインストール
    # yum -y install httpd-devel


    mod_fcgidをダウンロードして解凍
    # wget http://ftp.jaist.ac.jp/pub/apache//httpd/mod_fcgid/mod_fcgid-2.3.6.tar.gz
    # tar xzvf mod_fcgid-2.3.6.tar.gz


    mod_fcgidをビルドしてインストール
    # cd mod_fcgid-2.3.6
    # ./configure.apxs
    # make
    # make install



    dmdのインストール

    unzipも無ければ入れないといけません。
    # yum -y install unzip


    dmdのダウンロードと解凍と配置
    # wget http://ftp.digitalmars.com/dmd.2.055.zip
    # unzip dmd.2.055.zip
    # mv dmd2 /usr/local/


    dmdにシンボリックリンクを張る
    # cd /usr/local/bin/
    # ln -s /usr/local/dmd2/linux/bin64/dmd


    設定ファイルを設置
    # cp /usr/local/dmd2/linux/bin64/dmd.conf /etc/


    設定ファイルはフルパスで書く派です
    [Environment]
    
    DFLAGS=-I/usr/local/dmd2/src/phobos -I/usr/local/dmd2/src/druntime/import -L-L/usr/local/dmd2/linux/lib64 -L-L/usr/local/dmd2/linux/lib32 -L--no-warn-search-mismatch -L--export-dynamic -L-lrt



    アプリケーションのビルド

    アプリケーションのソースをダウンロードし、dmdでビルドします
    # dmd @switches


    出来た実行ファイルを設置します
    # mkdir /var/www/fcgi-bin/
    # mv bbs.fcgi /var/www/fcgi-bin/



    Apacheの設定

    mod_fcgidの設定を追加します。
    FcgidProcessTableFile /var/run/fcgid_shm
    FcgidIPCDir /tmp/fcgid_sock/
    FcgidMaxProcessesPerClass 1

    その他オプションについてはmod_fcgid公式を参照してください。


    fcgiファイルを置くディレクトリの設定を追加します。
    <Directory "/var/www/fcgi-bin/">
        AllowOverride None
        Options +ExecCGI
        Order allow,deny
        Allow from all
        SetHandler fcgid-script
    </Directory>



    /bbs/以下のアクセスが作成したfcgiファイルに行くよう設定します。
    RewriteEngine on
    RewriteRule ^/bbs/.*$ /var/www/fcgi-bin/bbs.fcgi [L]




    Apacheの起動

    mod_fcgidはSELinuxに弾かれるようなのでSELinuxは切ります。
    # echo 0 > /selinux/enforce


    また、CentOSのデフォルトiptablesは80ポートが塞がっているのでとりあえずクリアします。
    # iptables -F


    そうしましたらApacheを起動します。
    # service httpd start



    動作確認

    該当URLにアクセスします。
    http://hostname/bbs/ThreadList.html



    Hello work!!と表示されれば成功です。


    ソースについて

    modules以下にライブラリが入っていますが、これの内容ついては細かく触れません。使うだけです。
    アプリケーションのソースはsources以下にあります。


    エントリポイントはjp.ku6.bbs.mainモジュールにあります。
    記述量はそれほど無く、コメントも入れているのでなんとなく内容はわかるかと思います。
    1void main(string[] arguments)
    2{
    3    // フレームワークオブジェクトの生成
    4    auto raptan = new Raptan(8192, 8192, "/tmp");
    5
    6    // 拡張子を判断して自動でContent-Typeを出力する設定
    7    auto contentTypeFilter = new ContentTypeFilter;
    8    contentTypeFilter.add("html""text/html; charset=UTF-8");
    9    raptan.addFilter(contentTypeFilter);
    10
    11    // リクエストメソッドフィルタリング設定
    12    raptan.addFilter(new RequestMethodFilter(Request.Method.GET | Request.Method.POST));
    13
    14    // パスに対して処理を設定
    15    auto threadListAction = new ThreadListAction;
    16    raptan.setAction(APPLICATION_ROOT_URI ~ "/ThreadList.html", &threadListAction.execute);
    17
    18    // リクエストの受付を開始
    19    raptan.start();
    20
    21    // アプリケーションの終了を待機
    22    raptan.join();
    23}



    ポイントとしては、jp.ku6.raptan.core.RaptanがFastCGI用のフレームワークになっています。

    RaptanオブジェクトにURLのパスと処理内容のdelegateをセットで登録すると、
    そのURLにアクセスしたときに対応するdelegateが呼び出されます。
    1// パスに対して処理を設定
    2auto threadListAction = new ThreadListAction;
    3raptan.setAction(APPLICATION_ROOT_URI ~ "/ThreadList.html", &threadListAction.execute);


    セットしている処理内容はjp.ku6.bbs.action.ThreadListActionにあります。
    HTTP Responseオブジェクトに対してHTMLデータを出力しています。
    1string execute(Request request, Response response)
    2{
    3    // まずはHTMLテキストを出力するだけ
    4    response.append("<html><head><title>Hello work!!</title><body>Hello work!!</body></html>");
    5    return null;
    6}



    次回へ続く。

    コメントを書く

    名前
    本文
    編集用パスワード 入力すると編集が行えます
    管理者のみ閲覧