高自由度的 Web Desktop 服務?
說到高自由度的網上平台,你會想起哪一些網頁 / 平台? Google Drive? Facebook? Youtube? 還是說可以 post 奇怪照片的網站 Twitter(?) 平台自由度與用途 一般網頁都不會給予用家太高的自由度,這理由很簡單,一個網頁就是為了提供一種服務,無論那種服務所覆蓋的範圍是廣還是窄,以下是一些例子: draw.io → 網上圖表制作easyEDA → 網 上 PCB 制作與設計onlinesequencer → 網 上音樂制作facebook / twitter → 網 上社交分享Youtube / viemo / po***** → 網 上影片分享平台Office 365 / Google Document → 網上辦公軟件 所以,以商業角度來說,每一個平台必須要有他們的獨立功能才能夠有辦法營運,然而這亦會導致一些問題,就是平台依賴性 (Platform dependencies) 跟 供應商鎖定 (Vendor Lockdown) 問題。 為甚麼我應該擔心這些問題? 由於這篇文章不是說關於這些 WebApps 的問題,所以我也不詳細解釋這些問題了。簡單來說就是: 如果 A 網頁系統用的格式跟 B 網頁系統用的格式不一樣,你是沒辦法把檔案移動到另一平台上面如果提供 A 網頁系統的公司倒閉了,那你使用 A 系統編寫的檔案全部都再用不了 要解決這個問題,除了使用開放格式 / 標準格式(如 IEEE 制定的格式)外,就是開源系統本身了。但是, 真的這麼不幸擁有 A 系統的公司倒了,我想應該不太多人會懂得用開源的系統重建一套新系統出來吧?比較有可能的是會有人開發一個轉接器把 A 系統的格式轉成另一家 B 系統,但是這個也不是這麼容易可以做到,特別對於重度依賴 A系統並有大量 A 系統格式的檔案的人來說。有甚麼可能更槽糕?就是連檔案本身也是儲存在 A 系統裡面的,當 A 系統倒的時候檔案就跟著系統消失了。 以本地運作為前提設計的 WebApp 所以另一個想法,也就是 ArOZ Online 裡面一直在用的系統,就是把 WebApp 的擁有權取回來的方法。由用者擁有 WebApp 而不是由網頁提供者所擁有。這樣,就算供應該服務的公司倒了,WebApp 依舊能用,檔案也不會消失。例如好像說能在主機啟動的時候檢查更新,並把 WebApp 模組下載到啟動資料夾之類的。當然,你也可能會問: 這不就是 React Native 了嗎? 不對喔! (´・ω・`) 這裡就是 ArOZ Online 設計的不同了。React Native 針對的是本地的作業系統,例如 iOS,Windows 或是 MacOS,不同的作業系統會有不同的安裝檔,裡面各包一個 Chromium。那既然是這樣,那為甚麼不直接讓用家在 Chromium ( 或 Firefox / Chrome /Edge 之類的瀏覽器)打開你的 WebApp 呢?這樣不但省空間還能直接用標準 Web Standard 來開發模組。 而這個就是 ArOZ Online 的設計理念:屬於自己的 WebApp 伺服器;而且由於是使用 Web Protocol 傳送的,所以也跟其他 WebApp 一樣去到哪裡,甚至不需要是自己的電腦,都可以透過網絡存取到 WebApp 的內容。 論高自由度平台的條件 然而,因為這種設計已經脫離了一般 Web 開發的範圍,所以要開發一個這麼高自由度,多用途的系統會產生一大堆的問題,例如說 要重新設計 WebApp要想辦法解決本地檔案儲存問題怎樣以人性化的方式尋找及啟動 WebApp (aka 代替 Google 找 WebApp 的過程)怎樣讓使用者不用學習也能適應使用這套系統? 嗯?你有沒有覺得這些要求跟你平常在用的東西很像?沒錯,那就是作業系統 (Operating System),而作業系統本身也的確是一個很高自由度的東西,你可以把它用作 Media Center,可以用來辦公,遊戲,開發等等的用途。 我們需要的是一個能夠在網頁上運作的作業系統! 這個也是我開發 ArOZ Online 的理由:把自己需要的服務放到 Web Desktop 上,那去到世界各地,只要有網絡連接都能用自己的系統和存取到自己主機上的檔案。這跟 NAS 系統很像,只不過不同的地方在於這系統不單單用來放檔案,它亦能用來做其他事情。 這說起來簡單,做起來卻很複雜。這是因為自由度太高會導致很想意想不到的錯誤。好像說只是要處理使用者上載的檔案名稱就已經是一個大麻煩了。由於要跟其他系統兼容,所以不能隨便把檔案改名然後把原檔名放進資料庫這種 wordpress 般的操作;也不能讓使用者隨便把 ../ 放進去檔案路徑裡,就結果而言就是很多很多的麻煩。(有興趣的話可以參考這篇文章) 但是,經過了 Beta + 1.0 preview 差不多 5 年的開發和測試,最終於出來的效果也超乎了我的想像:一個用起來跟本地作業系統一樣的高自由度網頁桌面系統! 很有 Ubuntu…
ArOZ Online Pre-1.0 檔案存取路徑虛擬層
ArOZ Online BETA 與 Pre 1.0 版本的差別 在 ArOZ Online Pre-1.0 裡面,我幫 ArOZ Online 系統加上了一層虛擬層;你可能會問:為甚麼要加這個東西?這真是一個好問題,如果不是我開發過一個這樣的系統我也不知道檔案路徑虛擬化的重要性 問題一:檔案路徑安全性 一般如果你用 PHP 來寫系統,你很容易會使用一個檔案的真實路徑。舉個例子,你想讓用家選擇一個檔案,然後打開讓用家下載那個檔案,一般來說你會使用 realpath() 這個功能。然而,這有一定的危險性,例如有人在傳給伺服器的資料中加入 "../" ,讓他能離開你指定的存取範圍。 在 ArOZ Online Beta 的 implementation 中,由於所有檔案都是使用真實路徑存取的,這導致使用者很容易就可以在 path 裡面偷塞一點奇怪的字符以存取一些本來不應該被存取的東西。當然,你可以加一點東西來避免這問題,好像 Stack Overflow 上就有這樣的答案 Stack Overflow 上避免 PHP Directory Traversal 的方法 然而,每次都要透過一個特定的 function 來處理,總會有一天出問題的。(好像說某個開發者忘了用這個 function 或是這個 function 本身有 bug) 問題二:外置存取裝置 由於 ArOZ Online Beta 系統由原本的小網頁變成了一個類似作業系統的物體,它也需要去管理外置的存取裝置(如外接硬碟,或是 www root 所 mount 在的硬碟)。然而 PHP 並不是設計來做這樣的跨硬碟存取的,所以自然有不少的 Bug 存在,而開發起需要存取外置裝置的時候也特別麻煩,需要為。 在 ArOZ Online Beta 的 implementation 裡,使用者需要在 Apache conf 裡面設定 modXSendFile 來讓 PHP 可以在外置硬碟提供(serve)大型檔案如影片,音樂等等。然而,由於外置存取位置的路徑被直接寫進了 Apache conf,即使使用者想更改存取路徑也沒有辦法簡單完成。 解決方案:檔案路徑虛擬化 甚麼是路徑虛擬化?簡單來說就是把 file 的存取路徑進行轉換,讓不同的裝置也能夠輕易的讓模組使用 Virutalized path 來存取。簡單來說是這樣: 請求 Virtual Path模組把 Virtual Path 掉到 file system 的轉換 function回傳真實路徑處理資料 以 ArOZ Online Pre-1.0 的 File system listdir 功能來說,先假設你有兩隻 HDD mount 在了 /media/storage1 跟 /media/storage2,並把 storage.json 設定成以下的樣子: [ { "name":"Storage 1", "uuid":"S1", "path":"/media/storage1", "access":"everyone", "hierarchy":"users", "automount":true }, { "name":"Storage 2", "uuid":"S2", "path":"/media/storage2", "access":"everyone", "hierarchy":"public", "automount":true } ] 然後你可以傳入以下虛擬路徑用來處理檔案 S1:/video/ S2:/ user:/Music user:/Desktop/test 然而實際上,上術的虛擬路徑卻是在存取以下的真實路徑 /media/storage1/users/{username}/video /media/storage2/ ./files/users/{username}/Music ./files/users/{username}/Desktop/test/ 而設定當中,hierarchy 就是決定了虛擬路徑構造的元素,裡面的原理有點複雜,但是作為開發者,你只要存取 virtualPathToRealPath() 這個功能就能夠取得真實路徑了,簡單吧?
Drag & Drop 的重要性
https://www.youtube.com/watch?v=eCKVFfYGJfs&feature=youtu.be 之前的 ArOZ Online 系統一直都不支援 Drag & Drop,在使用起來雖然說沒甚麼大不了,就是有一點點的不方便,好像說選擇 File 要在 File Selector 裡面做,要移動 File 不是需要使用 Menu 就是需要使用 Hotkey 如 Ctrl C + Ctrl V 之類的。 AOB 大更新,支援 Drag Drop File Object 的 File Explorer 最新版本(v 20-3-2020)之後的 AOB 將會全面支援 File Drag Drop 。這到底是甚麼意思呢?簡單來說,這就是容許 File Explorer 對其他模組或另一個 File Explorer 視窗進行基於 Drag drop 的檔案移動。例如說你要把檔案由 A File Explorer 移動到 B File Explorer,這個時候你只需要把檔案由 A 拉到 B 即可,就像 Windows 一樣完全不用煩惱設定的問題,使用起來非常的直觀。 詳細的例子你可以看上面的 Youtube 影片了解更多。
OAO – 開源版本的 ArOZ Online 個人雲端平台
宣傳海報 自從 2016 年開發 ArOZ Online 系統之後就不斷有人跟我說這系統的價值和用途,當然這也是各有各的說法,從商業管理系統,多媒體創作平台,個人醫療管理到網絡硬碟等都有人提出過。當然,這對我來說是很榮幸的事情,畢竟這麼多人提出這麼多個用途,即是說這系統已經具有多周途的特點,可以隨個人需要而更改上面安裝的模塊以配合自己的需求。 現有的 ArOZ Online 版本 自這篇文章開始寫的今天開始計算,之前發佈的版本主要有以下幾個: 版本號代號發佈類型< dev-1.1.4Aloplex內部測試版< dev-1.2.8 Sempervivum Tectorum 內部測試版 1.0aCloud穩定版1.1aCloud - Oryza Sativa 內部測試版 1.2aCloud - Bombax Ceiba內部測試版 所以,如果要開源的話有兩個方向是可行的 使用獨立發行版本開源 使用獨立版本發行,即是說之後的 ArOZ Online 會分為兩個版本:1. ArOZ Online LTS (Long Term Support)2. Open ArOZ Online 這裡的好處就是我們可以透過 Long Term Support 的版本確保資金來源,再者確保開發進度和方向,然而不好的部分當然就是要分開兩個版本發行,由於系統組建不一樣,就結論來說組建的時候也會有很多問題,而且由 Open Source Community 提出的更改也很難直接進到主要的源碼庫,最後導致難以創造一個新的開源社群。 使用模組化方式開源 使用模組化開源的方式就比較特別,而且也應該比較少 Open Source Project 會使用這做法,畢竟這很容易導致版本不兼容的問題,但是我還是在這裡說一下這種開源方式的原理 模組開源方案 這種設計比較像 RedHat 之類的商業用 Linux 方案,然而要維護一點都不容易,再者,要實現這種開源的模組化設計還需要以下幾個系統功能: 模組安裝器(使用 Git 倉庫的 URL 來安裝)自動更新模組,用作更新 Open ArOZ Online 的基層架構開源模組的安裝需求及版本控制器(有點像 npm 的東西?) 所以,就現在的開發進度來說這種開源方式還是未能實現的。 結論 就開原模式來說的確使用模組化開源方案是比較合適的。然而,這會需要加入新的系統架構來作支援。看來在整個開源生態圈成熟之前還是只能用第一種方案:分成兩個組建的方式來開源會比較方便和符合成本效益了。
WordPress 與 ArOZ Online 模組
話說有一天我發現了你可以在側欄加入自定義的 HTML 代碼,試著試著,想不到連 Javascript 也能放進去 自定義的 HTML 欄位 於是我試了一下,果然真的能執行起來。 所以之後簡單的寫了一個轉接器把 ArOZ Online 上面的雲模組轉接過來 Wordpress 界面上使用,想不到居然真的能用。 NotepadA 模組在 Wordpress 上面啟動了 AirMusic 模組同樣也能在 Wordpress 界面上播放 果然 ArOZ Online 模組去到哪裡都能用真是有夠方便欸
一切都是 Windows 的錯:為甚麼 ArOZ Online 會出現 UM檔案 及 HEX資料夾 名命法
這甚麼爛東西,為甚麼要把一般的檔名全部編碼起來?那我用 Samba 的時候怎樣知道這個檔案是甚麼檔案?某 Beta 測試用家 沒錯,這一篇文章就是用來介紹到底為甚麼 ArOZ Online 要使用一個這麼麻煩的編碼方法來儲存檔案名稱及資料夾名稱。先由結論說起:這一切都是 Windows 的錯! 在這裡我先解釋一下甚麼是 UMFilename 跟 HexFoldername。這兩個是 ArOZ Online 用來給檔案及資料夾名稱編碼的方法,簡單來說就是把檔案名字使用 "inith" + bin2hex(原檔名) + "." + 原副檔名 和把資料夾使用 bin2hex(原資料夾名稱) 來編碼的一個神奇儲存方法。一般如果你在用 ArOZ Online 的檔案管理員你會看到有一些使用者自行上載的檔案會出現 綠色 或 藍色 底色的,那就是經編碼後的資料名稱。 HexFoldername 在 File Explorer 上顯示為綠色 UMFilename 在 File Explorer 上顯示為 藍色 故事起源: ArOZ Online Alpha ArOZ Online Alpha 是一套使用 PHP 5 編寫的影音串流系統,本來是用於 Windows + WAMP 的網頁伺服器架構上。而開發者我使用的 Windows 7 本身是 Big-5 編碼的,因此對中文的支援是完全 OK 的,但是我除了中文音樂之外也有聽日文的音樂,而問題就出在了這裡: PHP5 在讀取日文檔案名稱的時候出現亂碼。 ArOZ Online Alpha 的音樂播放界面 對於這個問題,基本上一般人想到的就只有這幾個解決方案: 把伺服器重灌,裝個 Unicode 版的 Windows 或者使用 Linux使用 Linux VM 並在 VM 裡面運行系統把檔案名稱全部放到 Database 裡,然後根據檔案路徑找到 Unicode 編碼的檔案名字。 然而,由於這套系統的無 DB 特性,第 3 點就不能用了;第 1, 2 點也太麻煩了完全不附合成本效益,所以最後的解決方法是:上載的時候使用 PHP 把檔名編碼成一個只使用 ASCII 的字串,然後以編碼字串來儲存,要讀取的時候從系統讀取檔名然後解碼出原本的檔名就好了。 可是,另一個問題就出現了。如果檔案名字本身就是以我編碼的方式儲存怎辦?例子: 音樂.mp3 -> abc.mp3 然後又剛好出現一個 abc.mp3?所以就乾脆直接在編碼後的檔案名字前加上 "inith" (Initiate with Hex Value),用以分辨是我方編碼的還是原本已經編碼的檔案,就是這樣,這種 UMFilename 的初型就出現了。 那為甚麼這種編碼方式叫做 UMFilename? 在剛開發 ArOZ Online Beta 的時候,最基礎的模組只有 Audio,Video 跟 Photo。基本上就是用以代替 ArOZ Online Alpha 的基本功能。 然而,這三個模組都需要上載功能,而由於 ArOZ Online Beta 的模組化設計原則,一個新的模塊被設計了出來: Upload Manager。 ArOZ Online Beta Audio 模組裡的 Upload Manager 界面 由於這個 Upload Manager 同樣遇上跟之前 Alpha 版本時的系統編碼問題,於是就直接把 Alpha 版的檔案名編碼方式搬過來了。而本來並沒有特別名稱的這種編碼方式也跟著這個模塊的名字改了起來,變成了 Upload Manager special File Naming Method,簡稱 UMFilename(或有人稱為 inith 命名法 或 inith filename)。 那 Hex Foldername 又是哪裡出來的? 在 ArOZ Online Beta 檔案管理員開發中的時候,一個 Bug 出現了。由於系統內的資料夾全部都是英文,直到桌面模組出現了之後才有機會因使用者新增資料夾的關系出現中文的資料夾名稱。到了中文的部分其實還是不大問題,因為中文還可以透過 PHP 的 mbstring 解決,然而日文的資料夾名稱就無法載入了。就結果而言,資料夾的命名需要另一個特別的編碼方法。 其實到發現這個問題的時候已經是滿後期的了,之前已經發生過不少因檔案名字過長而無法開啟的情況。(因為…
ArOZ Online 檔案選擇器
說到要在 WebApp 上讓使用者選擇檔案你會怎樣設計? 不少開發者都直接在 WebApp 裡面創建一個可以點選的列表就算數,能用但是不完美;所以在 ArOZ Online Base 系統架構裡面,我們在設計 File System 的時候就設計了一個可以輕易讓開發者使用的 檔案選擇器 ( File Selector ) 了。 ArOZ Online 系統下的 File Selector 所以,為啥我要用 FIle Selector?我自己幹一個就好了啊? 對,你也可以自己幹一個檔案選擇器,可是系統內建的 File Selector 有幾點用起來真的滿方便的。 預設支援 UM-FILENAME 及 HEX-FOLDERNAME 由於內建的檔案選擇器內建了 UM-Filename 跟 Hex-Foldername 的轉換程式,所以寫起來不必要特別自行處理這些特別的檔案命名方式。 Hex-foldername 顯示方法 UM-Filename 顯示方法 支援新增文件或資料夾 如果你需要新增一個文件或資料夾的時候,你可能要在 WebApp 裡面多加一個 <form> 元素,之後又需要增加一個處理的 php 甚麼的不是很麻煩嗎?用系統內置的 File Selector 就能直接省略這些問題,使用 Javascript callback 來取得使用者新建的文件名或資料夾名稱及位置。 新建文件的 File Selector 界面 使用方法 一般來說我們會建議使用者使用 Float Window 模式啟用 File Selector。然而,在一般網頁模式下啟動 File Selector 也是可以的,只不過使用體驗上會感覺到有點奇怪。首先,我們先從由 Float Window Mode 啟動 File Selector 的教學開始: 在 Float Window 模式下啟動檔案選擇器 先假設我們有這麼一個 function 來接收使用者選擇的檔案 function addFileFromSelector(fileData){ result = JSON.parse(fileData); for (var i=0; i < result.length; i++){ var filename = result[i].filename; var filepath = result[i].filepath; //DO SOMETHING HERE } } 以下是功能的啟動參數 ao_module_openFileSelector(uid,callBackFunctionName, windowWidth = 1080, windowHeight = 645, allowMultiple = false, selectMode = "file", newfname = "newfile.txt", umf = true) allowMultiple : 充許選擇多個檔案selectMode : (file / folder / mix / new),其意思為:只選擇檔案 / 只選擇資料夾 / 可選擇資料夾或檔案 / 新增文件或資料夾newfname : 新增檔案的預設名字(只在 selectMode = new 時有效)umf : 使用 UM-Filename 編碼檔案名字(只在 selectMode = new 時有效) //最基本的例子 var uid = ao_module_utils.getRandomUID(); ao_module_openFileSelector(uid,"addFileFromSelector",undefined,undefined,true); //自定義選擇器大小 var uid = ao_module_utils.getRandomUID(); ao_module_openFileSelector(uid,"addFileFromSelector",720,480,true); 你也可以透過 File Selector 為建立新的檔案名命,例子如下: var uid…
ArOZ Online 的 WebSocket 伺服器與 JWT 登入方法
ArOZ Online 一向也被人吐槽說沒有 Database 只能用 PHP 怎樣做即時通訊的 Web APP 呢?對,這真是一個好問題。 現在處理即時資料的方法 現在的 Web Desktop 模式即時更新方式 沒錯,這可能比你想像中的還要簡單,現在在 ArOZ Online 上處理即時資料的方法就是每隔一段時間做一次 AJAX Request 問伺服器的 php script 要一次資料。簡單來說就是每一個需要即時資料的模塊裡都會出現一段類似這樣的代碼: setInterval(function(){ $.ajax({url: url, success: function(data){ doSomething(data); }}); },1000); 這有甚麼不好嗎? 不好,這十分不好。首先, ArOZ Online 系統並沒有標準的 Database,所以 SQL 甚麼的都不能用。而且大部分模組開發者也不會這麼有空把 SQLite 塞進去,不少模塊也是直接拿 JSON 或 CSV 檔來儲存資料,就結果而言這種存取方法只會讓系統被 IO 速度卡住,想快也快不了。 所以 AOBWS 就出現了 甚麼是 aobws? aobws 就是 ArOZ Online 基礎系統的 WebSocket 伺服器。這系統有以下幾個特點: 支援 ArOZ Cluster 的 JWT 登入模式類 Minecraft 式指令模式以 Channel 分隔的 Broadcast 模式支援單用家多視窗登入 要用它的話跟一般 WebSocket 的使用方法很接近,簡單來說就是使用 ao_module 的 ws 模塊進行 init() 即可。以下是一個簡單的例子 aobws 網頁端啟動 function 例子 完整例子: https://github.com/aroz-online/aobws_demo/blob/master/index.php 那作為開發者 JWT 的部分我要怎樣處理? 這系統的好處就是你可以不用處理,只要填入 token = "" 即可自動彈出視窗讓使用者輸入 JWT token 值,是不是滿方便呢? JWT 請求授權界面 就是這樣,你的模組就能很方便的使用 aobws 作即時通訊了。 備注:如果我想用 aobws 作其他用途怎辦? 可以喔,你也可以在同一個 aob 主系統下使用多個 aobws 作其他用途。你可以在 SystemAOB/system/aobws 下找到啟動檔然後自行更改啟動設定。(主要是更改啟動的 port 跟 登入授權檢查的 URL)。以下為 aobws 的啟動參數: Usage of aobws.exe: -cert string Certification for TLS encription (default "server.crt") -endpt string ShadowJWT Validation Endpoint (default "http://localhost/AOB/SystemAOB/system/jwt/validate.php") -key string Server key for TLS encription (default "server.key") -port string HTTP service address (default "8000") -tls Enable TLS support on websocket (aka wss:// instead of ws://). Reqire -cert and -key