2 OpenWrt路由器系統開發與網頁設計


https://www.zhongkerd.com/news/content-729.html

 

摘 要: 目前商用WiFi路由器已應用到多個領域,商家通過給用戶提供一個穩定免費WiFi熱點達到吸引客戶、提升服務的目標。傳統路由器自帶的Luci界面提供了工廠模式的Web界面,用戶可通過該界面配置路由器。Luci采用MVC模式(Model-View-Controller)構造網頁,能實現動態的程序設計,便於修改和擴展。本文主要針對OpenWrt系統的路由器,介紹如何使用Lua和JavaScript腳本語言添加用戶模式Web界面。此外,還介紹了工廠模式和用戶模式之間的切換、添加Web頁面的方法,給出了一些應用實例。

0 引言

基於OpenWrt系統的家用路由器作為免費WiFi以及廣告投放的解決方案,具有成本低、部署靈活的優點,被廣告商家以及大型連鎖門店以集中投放、集中管理的方式運用[1]。采用該方式需要解決以下問題:精簡配置管理界面,便於大規模投放部署;屏蔽認證頁、廣告頁投放等設置,避免路由器的經營價值受損。因此需要在路由器管理界面中設定工廠模式以及用戶模式,以便於設備的管理、調試、部署[2]。

本文首先介紹了OpenWrt系統網頁的工作原理,然后具體介紹了如何添加用戶模式以及用戶模式和工廠模式的切換原理,接下來分析了基於Luci編寫網頁的具體過程。文章的最后對下一步的改進工作提出展望。

1 Luci搭建網頁

要理解Luci是如何搭建網頁的,首先就要了解Luci、Uhttpd、CGI、MVC幾個概念。

Luci是OpenWrt上的Web管理界面,它提供給用戶UCI、API接口組件,用於用戶在Web界面上對路由器進行管理與設置。Luci由Lua編寫完成,Lua是一種擴展語言,幾乎在所有操作系統和平台上都可以編譯、運行。實際上,Lua程序的工作流程是嵌入到其他的程序中運行的[3]。

Uhttpd是OpenWrt系統路由下的一個精簡的Web服務器,它具有非常低的內存開銷,CPU占用率低,效能好,通常用於輕量級的嵌入式設備[4]。Uhttpd是Luci默認的Web服務器,通過Web界面修改相關參數配置路由器。

CGI(Common Gateway Interface)是通用網關接口,它是外部應用程序與Web服務器之間的接口標准[5]。CGI規定了CGI程序和Web服務器之間傳遞信息的規則和流程[5]。通常Web服務器Uhttpd的功能並沒有強大到直接運行php、asp這樣的網頁文件,因此與第三方約定,把請求參數發送至第三方,然后接收第三方處理結果給客戶端。Lua語言編寫的Luci就是這個第三方。

用戶端與Web服務器Uhttpd使用CGI方式交互。Uhttpd服務器在工作過程中分叉出一個子進程,用於處理用戶的具體需求,然后傳遞給Luci,並在網頁中將子進程的結果進行顯示。

Luci、Uhttpd、CGI與網頁之間的關系如圖1所示。

基於OpenWrt系統路由器的模式切換與網頁設計

Luci采用MVC(Model-View-Controller)模式搭建網頁。MVC模式把軟件系統分為三個基本部分:模型(Model)、視圖(View)和控制器(Controller)。

(1)控制器(Controller):負責轉發和處理請求。

(2)視圖(View):設計的網頁界面。

(3)模型(Model):數據模型,是客觀事物的抽象。

使用MVC模式的目的是實現一種動態的程序設計,使后續對程序的修改和擴展簡化,並且使程序某一部分的重復利用成為可能[6]。

Controller、View、Model三者之間的關系如圖2所示[7]。

基於OpenWrt系統路由器的模式切換與網頁設計

2 用戶模式切換

2.1 MVC框架設計

Luci是一個單用戶框架,在/usr/lib/lua/luci/下有三個目錄,分別是model、view、controller,它們對應M、V、C[6]。公用的模塊放置在/usr/lib/lua/luci/controller/下面,各個用戶的模塊放置在該路徑下面對應的文件夾中。如路由器自帶的工廠模式就位於該目錄下的admin文件夾下。新增用戶模式需新添加文件夾mini,然后在該路徑下添加功能程序。這樣既有效地管理了不同管理員的權限,又有利於系統的拓展和維護。Controller、Model、View生成網頁的關系如圖3所示。

基於OpenWrt系統路由器的模式切換與網頁設計

在controller目錄下,每個Lua程序都以index作為起始函數。在index函數中,通過調用entry函數創建子節點,並把它放在全局節點樹的相應位置。entry函數的參數規定了該節點的位置屬性。

2.2 利用控制器生成Target

Controller目錄下的子節點以Target的方式生成網頁。Target是由每個子節點的entry函數創建的,這是dispatch流程最后要執行的方法。Target主要有alise、firstchild、call、cbi、form和template 6種生成方式。總體上可以分成兩類,前兩種主要用於鏈接其他節點,后四種則是實現函數方法或頁面跳轉[7]。

鏈接節點:alias是網頁節點之間的鏈接。比如,當用戶登錄路由成功后,進入的網頁節點未定義內容,可以用alias的方法,自動鏈接到有內容的Web節點。

實現函數方法或頁面跳轉:這種方法一般用於一個路徑的葉節點leaf,執行相應的操作,並且動態生成頁面html文件,傳遞給用戶。在call、cbi、form、template四種方法中,call調用了自定義的功能函數,直接調用以實現特定的目標,如發送數據、讀取文件等。調用cbi函數能夠使用CBI模塊簡潔高效地生成網頁。函數template是直接鏈接到目錄view下面的htm頁面,實現網頁跳轉。

如果要添加用戶模式(Mini),就必須在Controller目錄下添加文件夾mini。這樣Luci就能夠直接從Controller目錄下讀取子節點的數目及名稱,以便生成對應的節點樹。在用戶模式的mini目錄下至少添加兩個文件。第一個是index.lua文件,index.lua程序是為了實現用戶名、密碼的認證和網頁節點的配置。第二個是要具體實現的功能網頁,該網頁定義了生成的Target。以顯示路由系統狀態為例,需要添加index.lua和system_state.lua文件。

添加的用戶模式(Mini)文件結構如圖4所示。

要說明的是,此處system_state.lua規定是用template的方式生成Target,直接跳轉到view/mini文件夾下的system_state.htm文件。

實際上,用戶模式和工廠模式都是使用Luci搭建網頁,二者之間的原理完全相同。不同的是,在用戶模式下,給用戶顯示的是更加貼近實際使用需求的頁面。此外,使用用戶模式,關閉工廠模式的部分功能,還能使路由器更加高效地運轉。

在成功添加了用戶模式后,就要考慮登錄認證的問題。只有輸入正確的用戶名和密碼之后,才能成功登錄用戶模式。用戶模式下的所有子節點是由上而下逐層索引的,因此只要有一個節點需要認證,在該節點下的所有子節點也需要認證。只要mini節點有sysauth值,它以下的所有子節點都需要認證才能查看、操作。

此外,OpenWrt的精簡內核是單用戶機制,路由器自動以root用戶登錄。也就是說,工廠模式和用戶模式使用的是同一個用戶名和密碼。通過認證后,服務器端會發給用戶端一個session值,該值以cookie的形式存在於請求報文中,供服務器識別用戶。

2.3 Footer頁腳標簽

用戶成功登錄路由后,要求能夠在工廠模式與用戶模式之間自由切換。這個任務就由Footer頁腳標簽來完成。Footer的工作原理是由Luci的主題決定的,主題包含兩個內容,分別是header.htm和footer.htm。header.htm能顯示每個頁面的菜單欄,footer.htm則會讀取Controller目錄下的節點,最終顯示在頁腳中,以鏈接的方式切換用戶。

Footer頁腳標簽的工作原理如圖5所示。

基於OpenWrt系統路由器的模式切換與網頁設計

在成功添加頁腳之后,整個添加用戶模式和模式切換的工作就完成了。結果如圖6所示,其中footer.htm顯示在右下方,user model就是添加的用戶模式。

基於OpenWrt系統路由器的模式切換與網頁設計

3 網頁設計

前面提到,為了在用戶模式下生成滿足特定功能的網頁,需要在controller/mini目錄下添加index.lua和system_state.lua兩個文件。在system_state.lua中,規定網頁是以template的方式鏈接到view/mini文件下的system_state.htm文件。這樣只要設計system_state.htm的內容,就可以實現對應的功能。

system_state.htm是將Lua和JavaScript兩種語言配合使用來完成相應的功能。如果編寫的功能模塊不需要訪問路由器的數據,則利用Lua和JavaScript可以比較輕松地實現[4]。特別地,還可以調用一些輔助性Shell script。在網頁中,利用Lua語言的luci.sys.exec函數,就可以調用shell腳本。

例如,要測試路由器與外網是否連通,可以簡單地通過ping命令,訪問某一主流網站即可。如果ping通,則返回值為1,否則返回0。該功能可以用shell腳本寫,在網頁中使用如下命令:

state=tonumber(luci.sys.exec("/shellfun/pingtest"))

這樣就能執行/shellfun文件夾下的pingtest.sh Shell腳本,返回是否連通的狀態,在網頁中顯示相應的內容。

如果編寫的功能模塊需要訪問路由器的數據,這就需要一個從Lua腳本到JavaScript腳本數據交互的過程。因為JavaScript不太適合直接訪問路由器的數據,一般都是由Lua腳本程序讀取路由器的數據。然后,用JSON(JavaScript Object Notation)這種輕量級的數據交換格式發送給JavaScript腳本,利用JavaScript腳本在網頁上顯示出傳遞的數據。

例如,當要在網頁中顯示某一端口的實時流量時,需要不斷地訪問路由器的端口流量數據。可以在/luci/controller/mini的system_state.lua中某一節點規定,通過Lua的函數不斷地訪問數據,然后用JSON數據格式輸出數據[5]。在JavaScript腳本中,利用XHR.poll函數每隔一段時間接收JSON數據,最后將數據以圖表的方式動態顯示。

最終實現的路由器連通測試和流量監控結果如圖7所示。

基於OpenWrt系統路由器的模式切換與網頁設計

4 結論

本文深入地分析了路由器Web系統Luci搭建網頁的原理和實現細節。MVC模式是軟件工程實現網站搭建的核心,通過MVC模式,大大簡化了網站的開發和維護工作。在設計網頁的過程中,介紹了Lua和JavaScript如何進行數據交互,以及如何配合外部的shell腳本實現特定功能。

目前家用路由已經支持采用TF卡、U盤等外置存儲硬件,可以采用Luci搭建接口實現路由器本地存儲以及內容的投放,使之具有更高的運營價值和潛力。

 

關於:中科研拓

深圳市中科研拓科技有限公司專注提供軟件外包、app開發、智能硬件開發、O2O電商平台、手機應用程序、大數據系統、物聯網項目等開發外包服務,十年研發經驗,上百成功案例,中科院軟件外包合作企業。通過IT技術實現創造客戶和社會的價值,致力於為用戶提供很好的軟件解決方案。聯系電話400-0316-532,郵箱sales@zhongkerd.com,網址www.zhongkerd.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM