GoAhead使用記錄和資料整理

 

1. 基本概念
   1 簡介
廉價的硬件,功能強大的32操作系統,以及無處不在的因特網,它們一起促成了網絡應用和設備的飛速增長。大量的設備連接到網絡上,於是人們希望通過一種通用、熟悉、快捷的方式來訪問和控制它們。嵌入式web服務器正好迎合了這種需求,它們嵌入在網絡設備之中,使用標準的瀏覽器就可以遠程訪問和控制它們。
然而,並不是所有的web服務器都可以擔當如此重任,我們需要的是一個強大,安全,標準的,而且最好是久經考驗的嵌入式web服務器。這裏將要介紹的GoAhead嵌入式web服務器能夠滿足所有這些需求,包括西門子,霍尼韋爾,惠普等大型企業都在使用GoAhead。
2 嵌入式web服務器的要求
2.1 易於與設備集成
易於與設備集成包含兩個方面的意思,其一是將Web應用程序集成到實時操作系統,其二是可以在Web應用中輕鬆訪問硬件功能。由於GoAhead是開放源代碼的,因此這一點不難做到。
2.2 支持將Web頁面存儲在ROM中
許多嵌入式系統並沒有文件系統,因此有必要將web頁面保存到ROM中。GoAhead支持對web頁面進行編譯並將它們鏈接到最終的可執行文件中。
2.3 加密和用戶管理
GoAhead服務器支持使用SSL進行數據加密和認證。同時,它也支持摘要認證機制,一種總是加密密碼的更安全的認證機制。用戶管理功能允許不同的用戶具有不同級別的訪問權限。
除了上述要求之外,是否能夠快速、方便的生成動態頁面是衡量一個嵌入式web服務器的重要指標。GoAhead提供了多種方法編寫動態頁面,包括asp過程、GoForms過程和embedded javascript。GoAhead主要利用asp過程動態獲取系統信息然後顯示在頁面上,GoForms過程則主要用來處理用戶指令,例如控制設備和修改配置等。下面以一個動態顯示系統當前正在運行的進程信息的小型web應用程序爲例,闡述如何利用GoAhead構建嵌入式web應用程序,特別是asp和GoForms過程的使用方法。
3 動態頁面支持
在嵌入式設備中,大部分web頁面都是動態生成的。生成動態頁面的方法主要有兩種,通過C代碼生成HTML標籤和在HTML頁面中嵌入表達式標籤。直接通過C代碼生成頁面的優點是靈活,但是卻犧牲了友好性,因爲不到開始運行程序的最後一刻,你不可能知道這個頁面看起來會是個什麼樣子。相比之下,第二種方法更加直觀,你可以使用你所喜歡的工具以所見即所得的方式編輯頁面,在必要的地方添加佔位符,運行時它們會被動態產生的數據代替。GoAhead完全支持這兩種方式。
爲了方便的創建具有高度交互性的動態網頁,GoAhead提供了asp過程和GoForms過程兩種武器。它們實際上都與定義在服務器端的某個C函數綁定在一起,只是分工不同,asp過程用來生成顯示在頁面中的動態數據,而GoForms過程則用來處理用戶輸入和修改設置,它們一起構成了GoAhead的核心。
3.1 ASP過程
ASP最初用於IIS中,它是微軟開發的生成動態Web頁面的服務器端技術。現在已經被移植到包括GoAhead的各種平臺中,使用ASP的網頁的後綴一般爲“.asp”。爲了在Web頁面中嵌入ASP腳本,只需使用特殊的標籤“”將腳本包裹起來。之所以使用ASP標籤目的是爲了向用戶顯示動態內容,例如系統進程信息等。因爲動態內容實際上是在執行特定的C函數生成的,所以需要將web頁面中的ASP標籤與特定的C函數聯繫在一起。一般,整個過程大致可以分成以下三個步驟:
1. 設計web頁面,動態內容使用特定的asp過程名替代,也稱其爲一個佔位符。
2. 在某個.c文件中定義與asp過程對應的C函數
3. 在main.c文件中的initWebs函數中使用websAspDefine註冊asp過程
以清單1中的標籤爲例,此標籤的目的是爲了顯示系統當前正在運行的進程的信息。獲取進程信息實際上是由位於ui.c中的UpdateProcInfo函數完成的,詳見清單2,它負責獲取系統進程信息,並格式化爲HTML輸出。清單3中的websAspDefine函數將標籤與UpdateProcInfo函數關聯起來,這樣當GoAhead解析home.asp頁面遇到標籤時,控制權就會跳轉到UpdateProcInfor()函數,在輸出以HTML格式表示的進程信息後,控制權轉交給GoAhead繼續解析home.asp頁面。
注意:asp過程必須符合原型:int AspProcName (int ejid, webs_t wp, int argc, chart_t **argv);
其中,ejid參數作爲javascript解釋器句柄可以用來調用javascript相關函數,例如ejGetVar和ejSetResult。wp參數作爲瀏覽器連接的句柄,可以用來調用很多有用的GoAhead服務器函數,例如用來輸出HTML語句的websWrite等。argc和argv包含傳遞給asp過程的實參的個數和內容。
//清單1:home.asp(省略了其它無關的部分,細節請參考附帶源代碼)
html>
head>
WriteMetaElement(); %>
head>

form action="/goform/UpdateConfig" method="post">
input type="text" name="interval" value="" size="7" />
input type="submit" name="ok" value="Update" />
input type="reset" name="cancel" value="Reset" />
form>
UpdateProcInfo(); %>
html>
//清單2:ui.c
#include "ui.h"
#include "../webs.h"
//以HTML格式輸出系統當前進程信息
int UpdateProcInfo(int ejid, webs_t wp, int argc, char_t *argv)
{
return WriteProcPage(wp);
}
//根據用戶輸入改變刷新間隔時間設置
void UpdateConfig(webs_t wp, char_t *path, char_t *query)
{
int tmpInterval=_ttoi(websGetVar(wp, L"interval", L"-1"));
if(tmpInterval>3)
{
s_interval=tmpInterval;
}
websRedirect(wp, L"home.asp");
}
//清單3:main.c文件中的initWebs()函數
#include "ui.h"
//關聯asp標籤和C函數名字
websAspDefine(T("UpdateProcInfo"), UpdateProcInfo);
websAspDefine(T("WriteMetaElement"), WriteMetaElement);
//關聯GoForms標籤和C函數名字
websFormDefine(T("UpdateConfig"), UpdateConfig);
3.2 GoForms過程
GoAhead實現了稱爲GoForms的標準的通用網關接口(CGI)處理用戶提交的表單。與傳統的CGI方法不同,GoForms過程不是爲每個瀏覽器連接都創建一個新的進程,而是通過與GoAhead服務器共享地址空間,於是可以直接訪問全部的請求上下文。GoForms處理器可以自動解析和訪問所有的POST和查詢數據,它也提供了一組API可以輕鬆訪問CGI變量。
GoForms過程與ASP過程不同,它主要用來響應用戶輸入以更新系統設置或者執行特定的動作。在GoAhead中,GoForms實現爲一個URL處理器,它會解釋以"/goform"開始的URLs。緊跟着"goform"之後的字符串定義了表單名字和用戶請求的細節。例如:“/goform/ UpdateConfig?interval=5”這個請求表示調用GoForms過程" UpdateConfig ",GoForms變量interval表示用戶設置的新刷新間隔時間。GoAhead對ASP過程和GoForms過程的處理十分類似,只是GoForms過程通過websFormDefine函數調用進行關聯,並且必須遵守原型“void GoFormsProcName(webs_t wp, char_t *path, char_t *query);”。完整的GoForms過程示例請參考列表1-3中的用來處理用戶請求的UpdateConfig過程。
3.3 ROM化網頁
對於具有文件系統的嵌入式操作系統來說,可以將web應用中用到的各種資源,例如html文件、圖片、css文件以及exe文件直接以文件的形式保存起來。除此以外還存在大量的不具備文件系統的嵌入式操作系統,此時可以利用GoAhead的ROM化功能將所有資源集成到可執行文件中。首先在E:/GoAhead目錄下創建一個files.txt文件,將web應用中使用到的所有資源及其路徑都保存在這個文件中,如清單4所示:
//清單4:files.txt文件
E:/GoAhead/home.asp
E:/GoAhead/graphics/topbar.gif
E:/GoAhead/style/base.css
然後構建webcomp工程生成webcomp.exe。在命令行中輸入命令“webcomp E:/GoAhead files.txt >webrom.c”,此命令的目的是依次將files.txt中的每個資源文件都轉換爲一個unsigned char數組,並將這些數組添加到自動生成的webrom.c源文件中。最後,只需在webs工程中定義宏WEBS_PAGE_ROM以使能ROM化網頁功能,同時使用生成的webrom.c替換webs工程中的原始webrom.c,重新構建webs工程,這樣在生成的webs.exe中就包含了運行web應用所需的全部資源,大大簡化了部署過程。
3.4 測試web應用程序
運行webs.exe啓動GoAhead web服務器,打開瀏覽器在地址欄輸入
http://localhost/
。默認情況下會自動打開home.asp頁面,如圖1所示。
clip_image001screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.alt='Click here to open new window/nCTRL+Mouse wheel to zoom in/out';}" οnmοuseοver="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window/nCTRL+Mouse wheel to zoom in/out';}" οnclick="if(!this.resized) {return true;} else {window.open('http://images.cnblogs.com/cnblogs_com/dreamliner/WindowsLiveWriter/GoAheadweb_1294E/clip_image002_thumb.jpg');}" onmousewheel="return imgzoom(this);" alt="" />
圖1 GoAhead服務器測試頁面
   4 結語
GoAhead已經被成功的移植到HP-UX, Windows CE, pSOS, QNX, IRIX, uCOS, eCOS, chorus 和 RTEMS等衆多操作系統中。本文之所以使用Windows平臺上GoAhead移植爲例進行說明,一方面每個讀者都可以運行附帶的源代碼親自進行試驗以加深印象,另一方面也可以省略複雜的平臺介紹,從而重點掌握GoAhead本身的功能與特點。
筆者在利用GoAhead構建遠程監控等嵌入式web應用的過程中,發現有必要對GoAhead特有的一些編程技巧加以說明以少走彎路。GoAhead定義了宏T(x),可以根據是否定義了宏UNICODE使字符串在Unicode和ANSI之間自由切換。當使用websWrite函數輸出HTML語句時,請使用而不是/n輸出換行符。GoAhead中的一些選項,例如默認頁、端口號和重試次數等,都可以進行配置以適應自己的應用程序。另外如果希望爲用戶提供更加豐富的用戶體驗,可以考慮使用Java Applet技術。

2. 具體使用記錄

如何修改

默認主頁爲web文件夾下的home.asp,修改其中treeapp.asp爲非applet方式,舊瀏覽器無法訪問。

如何添加一個鏈接

在treeapp.asp中添加:

基本配置

參數配置

在頁面生成參數配置的超鏈接,處理這個超鏈接在umui.c中

static int aspGenerateConfigPage(int eid, webs_t wp,

int argc, char_t **argv)

{

char_t *userid;

a_assert(wp);

if(gstricmp(wp->query,"netcfg") == 0)

{

generateNetIfPage(wp);

}

else if(gstricmp(wp->query,"paramcfg") == 0)

{

generateParamCfgPage(wp);

}

}

的generateParamCfgPage函數中:

int generateParamCfgPage(webs_t wp)

{

int size = 0;

char temp[128];

char* output = (char*)malloc(4096);

strcpy(output, "

參數配置

");

strcat(output, "

");

strcat(output,"

strcat(output,"

");

strcat(output,"

");

{

sprintf(temp,"

打印調試信息 ");

}

strcat(output,temp);

strcat(output,"

");

{

sprintf(temp,"

保持來電");

}

strcat(output,temp);

strcat(output,"

");

strcat(output,"

");

strcat(output,"

");

strcat(output,"

");

websWrite(wp, output);

free(output);

return size;

}

aspGenerateConfigPage又被umui.c中void formDefineDeviceConfig(void)調用

void formDefineDeviceConfig(void)

{

websAspDefine(T("GenConfigPage"), aspGenerateConfigPage);

websFormDefine(T("ParamConfig"),formParamConfig);

}

在main.c中的initWebs中調用。

實際上

參數配置

中config.asp?paramcfg是調用paramcfg方法,

void formDefineDeviceConfig(void)

{

websAspDefine(T("GenConfigPage"), aspGenerateConfigPage);

}

將GenConfigPage字段與aspGenerateConfigPage關聯。主要是爲了此步,中間幾層是爲了分層功能。

接收處理部分:

int generateParamCfgPage(webs_t wp)中的

strcat(output, "

")指出由那個goform函數處理此form。

formDefineDeviceConfig中的

websFormDefine(T("ParamConfig"),formParamConfig);

將處理函數關聯到formParamConfig;

static void formParamConfig(webs_t wp, char_t *path, char_t *query)

{

char_t *ok;

a_assert(wp);

websHeader(wp);

websMsgStart(wp);

ok = websGetVar(wp, T("ok"), T(""));

if (gstricmp(ok, T("修改提交")) != 0)

{

websWrite(wp, T("放棄修改設備參數."));

}

else

{

websWrite(wp, T("線路參數修改成功,請點擊查看."));

}

websMsgEnd(wp);

websFooter(wp);

websDone(wp, 200);

}

ok = websGetVar(wp, T("ok"), T("")); 查找一個提交的form中變量的值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章