1. 程式人生 > IOS開發 >開動你的小手,nwjs 實現FTP客戶端

開動你的小手,nwjs 實現FTP客戶端

前言

基於什麼目的我會手動開發一個 FTP 客戶端呢?其實,很簡單,愛折騰,如果不是喜歡折騰,可能就不會對軟體開發如此痴迷,對其中的實現原理如此痴迷,一個不喜歡折騰的程式設計師,可能會失去方向感。最近公司整合第三方廠商的業務越來越多,SDK 也越來越大,SVN 伺服器不允許對超過 50 MB以上的 SDK 進行管理,那我們將這些 SDK 放哪兒呢?沒錯,就是 FTP 伺服器,過去的半年我作為 Mac 的使用者使用 FTP 體驗極其糟糕,系統的 Finder 訪問 FTP 伺服器無法訪問,線上的軟體也沒找到合適的,半年下來我搗鼓了虛擬機器器,裝了 Window10 ,在 Mac 和 Window10 之間,常年處於無縫切換的狀態。

事實上,出於對原理的好奇,決定動手開發 FTP 客戶端,開發過程總共 20 小時,大約 4 個晚上,中間也遇到過問題,也一併解決,整個兒過程下來,收穫頗豐。

基本功能概覽

客戶端下載地址 blogzzyc.obs.cn-east-2.myhuaweicloud.com/ipa/ftpclie…

  • FTP 檔案導航
  • 檔案下載
  • 刪除檔案
  • 右鍵檔案上傳
  • 右鍵新增資料夾

技術選型

FTP 業務的核心,一定是與伺服器的連線,在 gihtub 上找到了一個 4 年前的產物“node-ftp”。

整體檔案上看下來,功能齊全,手動測試了下,可以正常訪問 FTP 伺服器,於是就決定使用該模組。(這裡有一個小問題,我沒有全面測試 API,只測了一個連線的 API,導致在後續開發過程中使用 API 的時候 產生中文編碼問題,這裡體現了技術調研,一定要嚴謹,仔細)

客戶端容器使用 nwjs(node-webkit),實際上我對這個技術關注已久,一直沒有機會能夠動手實踐一下,這回終於讓我用上了,nwjs 實際上是一個 Hybrid App,你可以直接在容器中使用 nodejs 的 API 作為 Native Code,還是很爽的。

表現層,我則使用了 Vue+ElmemtUI,當下最火,開發效率高,非他們莫屬。

開始開發

廢話不說,直接上手幹,在網上找了一款現成的 Vue+ElementUI 後臺專案模版,一頓 npm instalnpm run serve ,將專案執行出來,迅速將模版中不需要的模組刪除,一番操作後,就遇到了第一個問題,Vue 的工程裡不能直接用 nodejs?使用 npm run serve

啟動了本地的開發服務,哦!?,需要將地址跑在 nwjs 裡才行吧,於是前往 nwjs.io 的官網,看了下檔案後,開啟了 remote-debug 模式,然後把地址放在除錯模式的容器中跑起來,這下應該成功了吧?,一執行,還是報紅,後來我仔細想了下,Webpack 有一個編譯過程,如果在 Vue 的工程中直接寫 nodejs 的程式碼,可能會被編譯 es5 其他的語法,機智如我,於是我在 public 目錄下新增 NWBridge.js 檔案,在 index.html 主動引入檔案,該檔案負責連線 Vue 的事件和 nodejs 的 API,再次執行,再次用 remote-debug 執行,還是不行,理論上這次應該是成功的,但是並沒有,我又想了下,是不是 nwjs 不允許線上地址呼叫 nodejs,我開啟 nwjs 的 DevTool,輸入了 location.href=開發地址,這次直接跑起來,但是 nodejs 的 API 依舊沒有呼叫成功,只剩下最後依照,只能打成 nwjs 本地除錯包,利用命令執行,接下來就是使用npm run build,然後增加 package.json 檔案,新增一個 nwjs 的開發目錄 nw,將生成的原始碼包和 package.json 檔案放進去,然後利用全域性命令nwjs ./nw,這一次執行成功,nodejs API 也呼叫成功了,心裡大喜,但是一想,每次修改東西都需要幹這件事情,太複雜,能不能將這件事情自動化,於是我就修改了 npm run build 命令,變成了如下 (vue-cli-service build)&&(rm -rf ./nw/dist)&&(mv dist ./nw)&&(nwjs ./nw) 一頓操作,搞定,這樣每次修改完後,只需要執行npm run build 就可以預覽、除錯了,到此,開發環境算是搭建好了。

頁面的怎麼開發的,就不說了,工作量也不多無非就那麼幾下,接下來準備對接第一個 API ,顯示目標伺服器的目錄,一頓搗鼓後,就有了如下效果:

很開心,於是對接各個模組的點選,進入子目錄,這時候遇到了嚴重的問題,中文目錄無法訪問,點選無效果,這個問題我花的時間最長,解決花了 6 個小時,這裡要注意我們一開始是拿不到中文目錄的,現在能看到中文是因為我使用了iconv-lite模組,對其進行 GBK 轉 UTF-8 編碼,所以可以看到中文目錄,FTP 的伺服器一定是個 Window 伺服器,因為 GBK 只有 Window 才有,而 nodejs 中不支援 GBK,所以需要這個著名的庫iconv-lite。到目前為止,表現層可能無法解決這個問題了,於是我將內容最小化,利用 js 指令碼直接執行中文命令,我發現不行,並不能訪問,所以不得不讀 node-ftp 的原始碼,原始碼比較少,我花了兩個小時就看完了,我發現其原理和 smtp、iamp 類似,同樣是架起 socket 連線指定伺服器,然後向管道里寫入 FTP 標準的指令,例如LIST命令,到這裡我突然理解,管道寫過來的是 GBK,寫回去的一定也是 GBK 才行,於是修改原始碼,將管道統一寫回的地方,利用 iconv-lite 進行一層轉換,可發現還是不行,於是我就取回管道過來的中文位元組,對其中的中文位元組手動篩選,找到指定檔名的中文變數,將位元組原封不動的從管道寫回去,這一次,成功了!!,這證明理論沒錯,於是我再次對寫死的中文,通過一層轉換寫回管道,可還是不行,這次又是為什麼呢?無奈,再次排查後,發現我直接用寫死的‘中文字串’,轉換出來的位元組和從FTP管道寫回來的中文引數轉換出來的位元組,差了一位,就因為一位導致無法執行命令,於是這一次,我直接用FTP管道寫回的中文變數,再次訪問其子目錄,果然這一次成功了。

放一張成功的圖,成功進入其他子目錄。

上述問題解決後,基本沒有大問題了,於是開始開發剩下的內容,其中包括上傳檔案下載檔案刪除檔案新增資料夾導航欄麵包屑FTP記錄讀寫等,這其中下載檔案遇到一個問題,檔案儲存對話方塊如何開啟,因為 <input type='file' /> 標籤只負責選擇上傳檔案操作,到這裡我想到 nwjs 容器應該會提供對應的方法,於是又再次前往 nwjs.io 官網閱讀檔案,果然讓我找到了如下內容:

果然 nwjs 對 input 標籤進行過載,讓他支援了檔案另存為,OK!!到此功能全部完成,最後開始打包我們的 App。

總結

為什麼我需要去做這件事情,因為有計劃就需要付諸實踐,否則想法只能留在腦海裡,nwjs 就留了很久,而做完這件事情後,我又發現自己對 Hybrid App 的理解更加深刻,作為程式設計師,主動性驅動很重要,一定要主動的發現需求,發現問題,主動的去溝通,去互動,程式設計師之間無非就是比誰先踏出自己的一畝三分地,誰先主動行動,誰才能收穫更多。