前言
Pascal 最具代表性的經典應用,莫過於以 Delphi 搭配 VCL 打造 Windows 圖形介面程式。在當時,這類桌面應用程式是市場的絕對主流。
近年來,終端使用者的軟體需求全面轉向網頁與行動應用。然而,Delphi 當時未能及時深化網頁技術的佈局,錯失了這波轉型的先機。
即便如此,現今若想以 Pascal 開發網頁程式,市場上有其對應的解決方案。本文將展示現代化 Pascal 網頁框架——Fano Framework 的實戰應用。
Fano Framework 的系統需求
Fano Framework 的系統需求如下:
- GNU/Linux
- Free Pascal
- libmicrohttpd
雖然 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.cgi 或 public/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 網頁程式的內建測試頁。經筆者測試,使用 PUT 或 DELETE 也可存取該頁面,不受傳統 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 網頁程式的測試頁。