ISAPI概述

    瞭解一下ISAPI(Internet Server API)在Microsoft產品中處於什麼位置,對於理解它本身不無幫助。實際上Visual C++提供了五個層次的支持,其中三個層次位於服務器上。另外兩個層次支持是客戶機專用的──你永遠不會在服務器上看到它們。下面將逐一定義各個層次支持並告訴你到哪裏去找到它們。
    ISAPI(服務器) 這是本章要討論的支持層。你需要給服務器本身提供一個擴展或過濾器。也就是說,客戶機不會直接與該層次支持打交道。它只能看到交互的結果。
    WinInet(服務器或客戶機) 本書不直接涉及該支持層次,但確實會間接地涉及到它。這些類允許你在客戶機和服務器之間使用專用的數據傳送方法。其中包含三種協議支持:HTTP、FTP和Gopher。從本質上看,你需要用這些類來創建一個會話(CInternetSession),它是服務器的一個連接,然後指定連接類型(CFtpConnection或者CHttpConnection)。建立連接後,你就可以進行工作了,比如查找文件等(CFtpFileFind或GopherFileFind)。通常你不必直接與這些類打交道,因爲Visual C++已經做好了一切,就像第12章創建URL moniker應用程序時一樣。
    異步URL moniker(服務器或客戶機) 第12章已經介紹了Visual C++ 的Internet支持的特定領域。要記住的是異步URL moniker允許你在Internet上完成任務而不必等待。只要簡單地告訴目標應用程序你想要什麼,然後就可以幹其它事情了。這裏的主要思想是,大部分情況下Internet不提供即時響應,如果不使用異步URL moniker方式,那麼對於長時間的下載,會使用戶的機器長時間地等待而無所事事。
    ActiveX document(客戶機) 該層次的支持在瀏覽器中顯示文檔並允許用戶編輯它。這些內容第11章都已經介紹過了。
    ActiveX控件(客戶機) 過去創建一個Web頁的基本元素要涉及到編寫大量的腳本,即使那樣,得到的也只是靜態的畫面。在Web站點上使用ActiveX控件意味着老的技術和靜態顯示再也不拖你的後腿了──現在的Web 頁可以根據具體情況發生變化。第10章介紹的就是該技術。
    Web鏈接 Internet上有許多地方可以獲得 IIS 、 ISAPI 以及其它與Internet服務器有關的技術(如Active Server Page( ASP) )。訪問IIS 信息的主要站點是 http://www.microsoft.com/ntserver/Basics/WebServices/default.asp。Microsoft支持的該站點包括了一些鏈接,它們指向你使用IIS本身所需的一切知識,甚至還有一些公用鏈接指向使能(Enabling)技術,(例如ISAPI)。如果你想獲得非Microsoft的幫助,可以訪問位於http://www.genusa.com/asp/的ASP開發者站點。它包含許多關於在Internet服務器上使用Active Server Pages的有價值的信息,另外它還有非Microsoft鏈接指向的IIS和ISAPI站點。
    在現實世界中使用ISAPI
    在現實世界產品環境中,你需要了解一些與ISAPI有關的事情。例如,你的ISA是要裝入服務器的一個DLL,這與其它DLL完全一樣。該DLL將與HTTP服務器共享同一地址空間,如果需要把該DLL佔用的內存用於其它用途,還可以卸載這個DLL。正是由於這一點,ISAPI才贏得了你的青睞。與其它技術(如CGI)比較起來,使用ISA有諸多好處,下面逐一予以介紹。
    內存佔用少 由於ISA是作爲DLL裝在服務器上的,並和HTTP服務器共用同一內存空間,所以不必浪費那些使用CGI時用到的內存。你真正要裝載的只是要求ISA完成任務所需的業務邏輯。
    速度 第一次裝載DLL與第一次裝載C應用程序所花費的時間基本相同,儘管DLL 因爲較小可能要快一些。不過,一旦第一次裝載了DLL後,它就常駐內存直至卸載它,這就意味着可以不必再花費裝載時間。而CGI腳本是每次調用時都裝載一次C應用程序。這可不是好消息。因爲ISA DLL與HTTP服務器共享同一內存空間,就不會爲進程間調用浪費時間了,也不會遇到在不同地址空間中使用C 應用程序時遇到的其它時間耗費問題。
    代碼共享 服務器的任務就是一次性裝入你的DLL。申請DLL服務的任意應用程序都可以訪問它。顯然,代碼共享是導致前兩點中提到的對CGI 進行改進來獲得低內存消耗和提高速度的因素之一,而且,代碼共享還帶來不那麼明顯看到的益處。例如,代碼共享減少了服務器的管理時間,因爲管理員只需要對給定的DLL 再產生一個副本去影響使用它的每一個應用程序。CGI通常使用的C應用程序有大量的冗餘代碼,改變一個單一例程,就需要對服務器上使用該例程的每一個C應用程序進行改變。這就意味着增加管理員的時間和程序員追蹤附加應用程序的需求。
    可靠性 CGI腳本使用的C應用程序在裝入服務器並在服務器上執行時,並沒有對服務器本身作多少訪問。因此,就難以創建一個C應用程序來監督服務器事件並從出錯中恢復。通常服務器總是終止出了錯的CGI,而客戶機卻什麼也不知道。ISA擁有對服務器的完全訪問,這就是說它們可以更容易地從出錯中恢復。於是,客戶機二次申請服務器的情況(即使有的話)非常少見。
    過濾能力 使用CGI和C應用程序,你不能提供與ISA一樣的事件驅動功能。原因很簡單:C應用程序是被調用、做工作、然後卸載。所以它沒有辦法長時間一直監視服務器事件。
    在一個DLL中的多任務能力 要CGI完成的每個任務都需要你有完成每個任務的單獨的可執行程序。結果導致過度調用每個例程。而 ISA 卻能包含多個命令,每個命令是CHttpServer類的一員。
    獲得這六項功能並不意味着在學習或寫出代碼方面付出昂貴代價。ISA就像CGI一樣好用。下面兩行代碼看上去就像是在應用程序中的代碼一樣。
    <!-這是帶有一個參數CGI例程的調用。->
    http://aux/controls/sample.exe?Param
    <!-這是帶有一個參數ISA例程的調用。->
    http://aux/contorls/sample.dll?Param
    可以看出操作ISAPI一點也不難。我們使用了與調用CGI例程幾乎完全一樣的代碼來調用ISA 控件。實際上,從編碼角度來看,唯一的不同就是ISA控件使用DLL擴展名,而CGI 例程使用EXE擴展名。從理論上來說,你可以將服務器轉換爲ISA,對Web 頁面作些檢索替換性的修改,這從用戶界面角度幾乎看不出什麼區別。當然,每個人都會注意到,因爲使用 ISAPI會帶來Web站點的更高效率。
    上面我提到的使用ISA的最後一個好處是,你可以用一個ISA完成多個任務。稍後將會介紹如何實現這種機制。現在你只需要知道,調用語法與以前調用標準CGI 沒什麼太多不同。下面就是一個ISA例程調用,它指明瞭你要使用DisplayStr函數。
    <!- 用一個參數在一個ISA例程中調用DisplayStr函數。->
    http://aux/controls/sample.DLL?DisplayStr?Param
    可以看出,在調用串中,我們使用第二個問號(?)調用了缺省任務之外的某種東西。第一個參數告訴服務器在SAMPLE.DLL中要調用哪個函數,第二個參數則包含一系列參數。這種調用函數的方法稱爲分析映射,本章“創建ISAPI擴展”一節將對如何創建它們作進一步介紹。
    注 給調用語法再加第二個問號就可以在ISA中調用缺省函數之外的東西。
    ISA確實還有一些與CGI相同的特性。例如,應用程序是在服務器而不是客戶機上運行的。這就使升級應用程序變得很容易──你要做的工作只是在服務器上更換一個DLL 文件(一定要終止服務才能更新DLL,不過這是方便地對機器進行更新所需付出的最小代價)。顯然,這比在訪問Web站點的每個客戶機上都替換一個應用程序要容易多了。這也正是目前各家公司都開始重視把內部網作爲承擔像幫助系統和定製數據庫應用程序這樣的主要任務的原因之一:更新一個服務器比更新許多客戶機要容易得多。
    注 ISA在服務器上運行,意味着每次更新一個定製應用程序時只需更新服務器而不用更新各個客戶機。
    技巧 IIS第4版添加了一些新功能,使得ISA更容易使用。例如,可以讓服務器在每次調用之後就卸載ISA。這意味着你能試試ISA,看它能否工作,如有必要,用新版本去替換一下,而這一切都是在不停止服務的條件下進行的。這一新功能的不足之處是,由於每當客戶機調用ISA時,服務器都需要重載它,這樣,就帶來一些操作問題。
    在過濾器與擴展之間進行抉擇
    你不必花太多時間就可以決定出是創建ISA過濾器還是創建ISA擴展(或者兩個都創建)。這兩種ISA之間的區別很明顯。知道它們的差別後選擇所需的ISA就是件簡單的事了。
    過濾器總是對服務器本身的事件作出反應。如果用戶試圖登錄Web站點,就會生成ISA過濾器能監測到的一個事件。通常用過濾器來修改客戶機與服務器之間的數據流。例如,如果應用程序發現有SF_NOTIFY_AUTHENTICATION事件發生,就可以顯示一個對話框,要求用戶輸入名稱和口令。如果名稱和口令都正確,用戶即可獲得對Web站點的訪問權。
    擴展適用於CGI同樣的情形。例如,如果想創建一個訂貨系統,就可以使用擴展。擴展將接收用戶填入窗體中的數據,處理信息並將它們加入數據庫,最後將某種形式的收據發還給用戶。這正是使用CGI腳本時遵循的同一過程;唯一的區別是現在使用的是DLL。與過濾器不同,擴展不監測服務器上的事件,無論從哪一方面看它都像應用程序那樣工作。
    還有一些情況,不管選擇過濾器還是擴展都沒什麼關係。例如,考慮一個簡單的Web 計數器。每次有人訪問Web站點時,都更新計數器並顯示它們是第幾位訪問者。如果願意的話,你可以從Web頁面上調用ISA擴展來更新計數器,也可以用過濾器監測服務器上的SF_NOTIFY_LOG事件並自動發送信息。這只是個人喜好問題。
    注 像訪問計數器這類的ISA應用程序,我們既可以選擇創建過濾器,也可選擇創建擴展。
    你可能還會遇到需要同時使用擴展和過濾器的情形。例如,你可能想爲授權的Netscape用戶顯示一種Web頁,而給非授權Netscape用戶顯示另一種Web頁。針對授權的和非授權的Internet Explorer用戶也有兩個Web頁。這種情況下需要在HTML格式中編寫一些腳本來檢測瀏覽器類型,需要用過濾器來檢查用戶是否授權,還需要用擴展來生成正確的頁面。在服務器中將客戶機腳本和ISA擴展進行組合,將大大豐富你的Web站點並使它便於每個人使用。
    注 某些ISA應用程序(如專用的瀏覽器支持),要求創建既包括過濾器又包括擴展的複雜的DLL。
    使用ISAPI的五個類
    前面已經說過本章將使用五個新的MFC類。這並不是說你不再使用那些以前已經熟悉的類了,不過這些類確實能提供設計ISA過濾器或擴展所需的特殊功能。下面將對下面章節中要用的這些類作簡單的介紹。顯然在開始設計真正的示例代碼時你的瞭解會更深入一些的。
    CHttpServer 這是創建過濾器或擴展所需的主要類。CHttpServer類定義了一個作爲服務器擴展DLL或ISA的對象。該CHttpServer 對象的主要目的是處理由服務器和客戶機生成的消息。所以任何ISA DLL中只有一個CHttpServer對象。
    CHttpServerContext CHttpServer真正創建了該對象,它是來自客戶機的某個單一請求的單一實例。也就是說,對每個活動的客戶機請求,都有一個CHttpServerContext對象。當客戶機請求完成後該對象即被清除。
     CHttpFilter ISA過濾器要求使用特殊的 CHttpFilter對象來管理服務器的事件。該對象負責查找所有客戶機與服務器交互時由服務器生成的SF消息。例如,每次用戶試圖訪問Web站點時,客戶機都會生成一個SF_NOTIFY_LOG消息。
    CHttpFilterContext CHttpFilter 對象將爲每個活動的服務器事件創建一個 CHttpFilterContext對象。CHttpFilterContext類表示在特定會話中由單個客戶機形成的單個事件。
    CHtmlStream 利用該類來管理客戶機和服務器間的數據。無論何時當CHttpServer類需要在客戶機和服務器之間傳遞信息時,都會創建該類的對象。大部分情況下每個DLL只有一個這樣的對象。不過,CHttpServer對象爲了安全傳遞數據可以創建所需的任意多的CHtmlStream對象。典型的CHtmlStream對象包含創建HTML頁內容所需的數據和所有標記。例如,如果你是檢索數據庫,那麼結果的CHtmlStream 對象就不僅包含數據,還包括實際創建的用來顯示數據Web頁所需的HTML標記(參見第8章有關HTML標記的介紹)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章