Pascal 網頁程式設計教學:Fano Framework 入門

【分享文章】
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

    前言

    Pascal 早期的經典應用是用 Delphi 搭配 VCL (Visual Component Library) 寫 Windows 圖形界面程式。當時這種型態的應用程式是主流。

    近年來,一般使用者 (end user) 層級的軟體轉成網頁程式 (web application) 和行動程式 (mobile application)。然而,Delphi 當時沒有加強網頁程式相關的應用,未能及時趕上這波風潮。

    不過,如果想用 Pascal 寫網頁程式,仍然有一些方案可選擇。本文介紹了數個用 Pascal 寫網頁程式的方案。並展示 Fano Framework 的使用方式。

    Pascal 網頁程式設計方案

    CGI

    Free Pascal 官方的 fcl-web 模組就是用來撰寫 CGI 或 FastCGI 程式的模組。或者,也可以像我們先前的文章般,不使用 CGI 模組,僅使用 CGI 的概念手刻 CGI 程式。

    然而,現在甚少網頁程式設計師會繼續使用 CGI 來撰寫網頁程式。通常只用在小型網頁程式或嵌入式網頁程式中。我們在前文有展示過簡單的 CGI 程式,本文不繼續使用 CGI。

    Brook Framework 和 Brook for Free Pascal

    Brook 網頁程式有兩個版本,一種是純粹以 Pascal 實作的 Brook for Free Pascal,一種是混合 Pascal 和 C 的 Brook Framework。目前無法確定之後會兩者並行或是以 Brook Framework 為主。根據 Brook Framework 的說明,該框架是微框架 (micro-framework)。

    目前 (西元 2020 年三月) Brook 似乎還在建置中,文件相當缺乏,只能透過一些範例及 Brook 的範例及原始碼來學習。所以我們不使用這套框架,或許過一陣子再注意一下 Brook 的發展。

    Fano Framework

    Fano Framework 比較符合程式設計者對現代化網頁框架的預期,有 MVC 模式、資料庫連接、表單檢查、使用者權限等。而且,Fano Framework 也有官網,用來說明該網頁框架的使用方式。

    雖然目前 Fano Framework 只能在 GNU/Linux 上運作,但大部分的網頁程式也是架設在某種 GNU/Linux 發行版上,所以這項限制的影響不若想像地大。

    本文會使用 Fano Framework 來展示以 Pascal 建立網頁程式的過程。

    Synopse mORMot Framework

    mORMot Framework 是一個完整的網頁框架,該框架強調 ORM (Object Relational Mapping)、SOA (Service-Oriented Architecture) 等概念。不限於網頁程式,mORMot 的客戶端也可能是 Delphi 程式或其他的程式。

    由於 mORMot Framework 比較複雜,導致該框架的官方文件十分冗長、不易閱讀。所以筆者未選擇該框架。有興趣的讀者可以自行到 mORMot 的官網看看。

    Delphi RAD Server

    Delphi 在 Enterprise (含) 以上的版本加上網頁程式的功能。從 Delphi 的官網來看,RAD Server 加調 REST API 服務,可連結資料庫等外部服務,可管理使用者權限等,也有製作使用者界面的功能。

    由於 Delphi Enterprise 版本是商業軟體,對於第一次學習用 Pascal 寫網頁程式的程式設計者來說,應該不會馬上使用該方案。故我們不介紹該軟體。

    Fano Framework 的系統需求

    Fano Framework 的系統需求如下:

    雖然 Fano Framework 的官方 repo 中可見到一些 Windows 終端機腳本,經筆者實測,目前 Fano Framework 仍然無法在 Windows 上編譯。這可能是日後會加入的支援平台。

    此外,Fano Framework 也無法在 macOS 或 FreeBSD 中編譯。目前應該只能在 GNU/Linux 系統下編譯和運行。

    雖然 Fano Framework 的官網沒有提到 libmicrohttpd,經筆者實測,發現未安裝該函式庫時會無法編譯 Fano 專案,故我們將其列入相依性。在主流 GNU/Linux 發行版上,都有預編好的 libmicrohttpd 套件,不會太難安裝。

    編譯 Fano CLI

    Fano CLI 是 Fano Framework 的專案生成器 (scaffolding tool)。透過 Fano CLI,我們可以取得相對一致的專案架構,減少重覆的專案建置任務。

    目前 Fano CLI 沒有發佈 GNU/Linux 套件,得自行編譯。以下是編譯 Fano CLI 的步驟:

    $ git clone https://github.com/fanoframework/fano-cli.git
    $ cd fano-cli
    $ ./tools/config.setup.sh
    $ ./build.sh
    

    編譯完成後,可在 bin/out 目錄取得 fanocli。將該命令列工具移至 PATH 所在的目錄即可。

    建立 Fano 網頁程式專案

    Fano CLI 所生成的專案大同小異,主要的差別在其部署 (deployment) 方式。以下是生成 Fano 專案時可選的部署方式:

    • CGI
    • FastCGI
    • SCGI
    • uWSGI
    • 內嵌網頁伺服器 (embedded web server)

    前三者皆基於 CGI 界面。而 uWSGI 主要是 Python 社群的網頁程式所用的界面。至於內建伺服器則是現代網頁框架常見的方式。

    原本的 CGI 程式每次回應時都要開新的行程,在網站訪問者多時開銷較大,故不建議使用。其他的界面則可依讀者的喜好來選擇。

    Fano 專案的內嵌網頁伺服器是 libmicrohttpd,該函式庫是以 C 實作的輕量內嵌網頁伺服器,應該足以直接上線使用,而不僅僅是開發時期伺服器。

    根據上述的部署模式,可使用相對應的命令列參數:

    • --project-cgi=:使用 CGI 界面
    • --project-fcgi=:使用 FastCGI 界面
    • --project-fcgid=:使用 FastCGI 界面,生成 Apache 模組
    • --project-scgi=:使用 SCGI 界面
    • --project-uwsgi=:使用 uWSGI 界面
    • --project-mhd=:使用內嵌網頁伺服器

    假定專案為 myapp ,使用以下指令來建立基於 FastCGI 的 Fano 專案:

    $ fanocli --project-fcgi=myapp
    

    這時候 fanocli 會建立 myapp 目錄,並將建好的專案放入該目錄。

    若想用內嵌網頁伺服器,則改用以下指令:

    $ fanocli --project-mhd=myapp
    

    管理 Fano 專案時,會假定工作目錄為 Fano 專案的根目錄,故我們將工作目錄移至建好的 Fano 專案的根目錄:

    $ cd path/to/myapp
    

    假定我們已經對該專案做好適當的增修,使用專案內附的命令稿來編譯網頁程式:

    $ ./build.sh
    

    基本上,每次有更動時,都要重新編譯以產生新的網頁程式。由於 Free Pascal 編譯的速度還算快,而且每次編譯時只會修改異動的部分,故編譯時的等待時間不會太長。

    如果仔細觀察 Fano 專案,會發現其實 Fano Framework 把整個函式庫放在 vendor 子目錄中,在編譯時會一併編入網頁程式中。所以我們不需要額外安裝 Fano Framework。

    編譯完後,網頁程式為 bin/app.cgipublic/app.cgi ,視專案設定而定。請注意一下編譯的訊息。

    如果讀者想先試用一下 Fano Framework,也可以不修改專案的程式碼直接編譯,這時候會在網站的根目錄看到 Fano 網頁程式的內建測試頁。

    雖然清除目的檔 (object file) 不是必要的,若讀者為了某些考量想清掉目的檔,可使用以下命令稿:

    $ ./tools/clean.sh
    

    部署 Fano 網頁程式

    使用新的網頁框架時,最好先練習在內部部署程式。程式能動是最基本的,之後再來求功能完整,更進一步時再求效能良好。

    在本節中,我們會使用 Debian 相容系統,將網頁程式部署到 Nginx 上,分別使用 FastCGI 和內嵌網頁伺服器。

    使用 FastCGI

    /etc/nginx/site-enabled/default 修改如下:

    server {
    	listen 80 default_server;
    	listen [::]:80 default_server;
    
    	root /var/www;
    
    	server_name localhost;
    
    	location / {
    		fastcgi_pass 127.0.0.1:20477;
    		include fastcgi_params;
    	}
    }
    

    由於 Nginx 支援 FastCGI 界面,可以直接和我們寫好的網頁程式溝通。若讀者使用 SCGI 或 uWSGI 來部署程式,只要對設定檔略為修改即可。但 Nginx 不支援 CGI 界面,得用先前介紹的 FCGI wrap 來包 CGI 程式。

    設置好後,重開 Nginx 伺服器:

    $ sudo systemctl restart nginx
    

    移動到 Fano 專案所在的根目錄,並啟動 Fano 網頁程式:

    $ cd path/to/myapp
    $ ./bin/app.cgi
    

    用瀏覽器或 HTTP 客戶端程式拜訪 http://localhost 即可看到 Fano 網頁程式的內建測試頁。經筆者測試,使用 PUTDELETE 也可存取該頁面,不受傳統 CGI 程式的限制。

    使用內建網頁伺服器

    當我們使用內建網頁伺服器來部署網頁程式時,Nginx 的角色變成反向代理者 (reverse proxy)。只要網頁框架內建的網頁伺服器的效能不要太差,使用這種方式來部署網頁程式反而更簡單。

    /etc/nginx/site-enabled/default 修改如下:

    server {
    	listen 80 default_server;
    	listen [::]:80 default_server;
    
    	root /var/www;
    
    	server_name localhost;
    
    	location / {
    		proxy_pass http://127.0.0.1:20477;
    	}
    }
    

    設置好後,重開 Nginx 伺服器:

    $ sudo systemctl restart nginx
    

    移動到 Fano 專案所在的根目錄,並啟動 Fano 網頁程式:

    $ cd path/to/myapp
    $ ./bin/app.cgi
    

    拜訪 http://localhost 即可看到 Fano 網頁程式的測試頁。

    【分享文章】
    Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email
    【追蹤網站】
    Facebook Twitter Plurk
    臉書討論區