RDS簡介
RDS Red Dot Sight 紅點瞄準器 是步槍等軍械上的機瞄裝置,用以輔助瞄準。
RDS(Remote Data Services,遠程數據服務)是允許我們處理客戶端數據的一系列服務的統稱。現在不用擔心這方面的問題,因為RDS本身就是ADO的一部分,只有在需要傳送和使用客戶端數據時,才會使用。遠程數據服務RDS允許程式設計師開發原生的WINDOWS分散式多層套用系統,或是開發以瀏覽器為圖形用戶接口的WEB套用系統。
遠程數據服務RDS提供了客戶端應用程式在INTERNET/INTRANET或分散式環境中使用ADO中RECORDSET對象的能力。
可以在瀏覽器中通過遠程數據服務RDS取得RECORDSET對象,然後在腳本語言中存取數據。或在原生WINDOWS應用程式中通過RDS取得RECORDSET對象,然後使用程式代碼來存取遠程數據源中的數據。RDS能夠將ADO取得的數據一DCOM或HTTP通信協定由中介軟體或中介組件傳遞給客戶端,並且把數據快取在客戶端中讓客戶端存取數據。
伺服器
雖然RDS用於傳送和訪問客戶端數據,但其確實有一些基於伺服器的組件。這是必需的,因為肯定需要某種方式將數據傳送到客戶端。因此有了一系列能訪問數據並允許傳送數據到客戶端的伺服器組件。我們把實際的數據傳送稱為調度(marshal)。
伺服器端組件圖的最上端是數據存儲,由OLE DB提供者訪問。它並不是RDS的一部分,但這表示只要有相應的OLE DB提供者,就可以通過RDS在客戶端使用任何數據。至於如何處理伺服器上的數據,可以有兩種選擇:· 數據工廠(DataFactory)是預設的用於訪問數據存儲的伺服器端組件。它作為伺服器端RDS組件的一部分安裝在計算機上,除了能從數據存儲中獲取數據外,還為伺服器處理髮送到客戶端以及從客戶端傳送來的數據。· 自定義組件只是一個普通的提供了數據傳送方法的COM組件。當數據工廠不能提供所需的功能時,可以使用自定義組件。本章將介紹一個簡單的組件例子,在本書的後面還有一個更複雜的例子。Web伺服器使用這兩種組件作為客戶和伺服器數據的接口。
客戶組件
在客戶端先從底端的DataSpace對象開始,該對象作為客戶端的一部分與數據工廠或自定義對象協同工作。DataSpace對象是一個代理對象,負責與伺服器進行通信,同時也是數據傳輸的通道(或者通常所說的調度)。DataSpace對象是用客戶端腳本語言或用HTML語言中的標記創建的COM對象。在本章後面會看到關於這方面的例子。
DataSpace對象上面是數據源對象(Data Source Object,DSO),負責存儲客戶端數據。一個數據源對象?數據。客戶數據快取只是一種管理客戶端數據的客戶游標服務。同時數據源對象又是一個COM對象,與DataSpace對象類似,也可以通過客戶端腳本或使用HTML語言中的標記來創建。同樣,在本章稍後也會介紹關於這方面的一些例子。數據源對象的上面是數據綁定管理器,任務是建立HTML控制項與數據源對象的連線。這就是我們所知道的綁定,可以通過設定某些HTML控制項的DATASRC和DATAFLD屬性來實現。下面將對這些內容進行討論,並示範如何在瀏覽器中方便地使用數據。
瀏覽器
要知道RDS是微軟的技術,因此只能在微軟的瀏覽器上工作。實際上,只有在IE 4.0或者更高版本的瀏覽器中才完全支持RDS。
當編寫依賴於RDS的應用程式時,需要注意訪問應用程式的客戶的RDS版本可能與伺服器端有所不同。舉例來說,IE 4中的是RDS 1.5版本,而IE 5、Office 2000和Visual Studio 6中的則是RDS 2.0版本。有兩種方法可以處理這種兼容性問題:
· 確保所有用戶已經升級到RDS的最新版本。如果客戶運行的是Windows 2000,那么已經在運行最新版本的RDS了。RDS 2.5版本是目前最新的隨同Windows 2000一起發布的版本,同時也是一個可單獨下載的軟體包。· 當連線到數據源時,指定數據工廠的模式。這可以指定使用的是哪一個版本的RDS組件,後面將介紹這方面的一個例子。
數據控制項
我們將依次介紹這些數據控制項,一旦了解了如何用它們把數據傳送到客戶端,將會介紹如何使用這些數據。
表格數據控制項
表格數據控制項(Tabular Data Control,TDC)是最簡單的數據源對象,主要用於少量的唯讀數據,特別是那些從不改變或很少修改的,不需要從客戶端進行更新的靜態數據。例如,表格數據控制項能提供一個網頁內的選單項或連結的列表。
通過在HTML代碼中使用標記可以創建一個表格數據控制項。參數DataURL可以指定包含文本數據的檔案名稱。
TDC唯讀取表格中的數據或標記為表格形式的數據,例如,可以處理逗號分隔形式的數據(Comma Separated Value, CSV),類似於下面的數據:"172-32-1176","White","Bob","408 496-7223""219-46-8915","Green","Marjorie","415 986-7020""238-95-7766","Carson","Cheryl","415 548-7723""267-41-2394","O'Leary","Michael","408 286-2428""274-80-9391","Straight","Dean","415 834-2919""341-22-1782","Smith","Meander","913 843-0462""409-56-7008","Bennet","Abraham","415 658-9932"TDC也可以自由定義。除?記的參數項或編寫腳本代碼來配置這些參數。參數的說明如表10-1所示:
下面是使用參數創建TDC的一個例子。也可以在客戶端腳本中獲取數據,下面的例子顯示了給TDC載入數據的JScript腳本。function fillTDC(){ dsoAuthors.dataURL = 'authors.csv'; dsoAuthors.Reset();}如果改變了TDC的DataURL參數,必須使用Reset方法,這樣才能使新的URL起作用。當介紹數據綁定時,會更詳細地討論如何使用它。Reset方法是TDC唯一的一個方法。 2. RDS數據控制項 RDS數據控制項能夠訪問一般的數據存儲,而不是平面檔案。它通常用於連線SQL資料庫以從表、查詢或存儲過程獲取數據。與TDC不同,RDS數據控制項允許更新數據。在本章稍後通過示例說明如何進行數據更新。類似於TDC,可以用HTML腳本中的OBJECT標記來創建一個RDS數據控制項,並以類似的方式設定其屬性。authorsonclick="resetData('publishers')">publishers下面創建虛表。 這充當了模板的作用。注意,表格中還沒有單元格。這是因為並不知道數據有多少個欄位,所以也將在運行期間創建它們。現在編寫JScript代碼。首先看一下resetData函式,該函式設定數據控制項的屬性並載入數據。function resetData(sTable){ // reset the data dsoData.Connect = 'Provider=SQLOLEDB; Data Source=" + "' + '; Initial Catalog=pubs; User ID=sa; Password="; dsoData.Server = "http://'; dsoData.SQL = 'SELECT * FROM ' + sTable; dsoData.Refresh();} 雖然這看起來比使用參數更複雜一些,但是仍然比較簡單。別忘了參數名是如何映射到屬性的?這裡所做的就是設定那些屬性,然後調用Refresh方法更新數據控制項。看上去,這可能比以前的例子更糟糕,因為在代碼中只有不多的ASP,也只是簡單地在屬性中填入Web伺服器的名字。但使用該方法可以在不修改代碼的情況下將此ASP頁面從一個伺服器移到另一個伺服器。作為數據源的表名可以通過選擇適當的按鈕而傳給函式。一旦載入了數據,將觸發數據控制項的ondatasetcomplete事件,運行createCells函式。function createCells(){ var fldF; var tblCell; // delete what's there already deleteCells(); // now create the new cells for (fldF = new Enumerator(dsoData.recordset.Fields); !fldF.atEnd(); fldF.moveNext()) { // create a new cell for the heading tblCell = tblData.rows【0】.insertCell(); tblCell.innerHTML = '' + fldF.item().name + ''; // create a new cell for the body tblCell = tblData.rows【1】.insertCell(); tblCell.innerHTML = ' fldF.item().name + '">'; } // now bind to the data source tblData.dataSrc = '#dsoData';}這同樣也很簡單。首先刪除了現有的表格單元格(馬上會介紹這個函式),然後遍歷記錄集的欄位。在行頭為每個欄位創建一個新單元格(這個表格只有兩行:第一行,即第0行,是表頭;第二行,即第1行,是表體)。表格單元創建完後,將innerHTML屬性設為對應的欄位名。在表體中創建新單元格的過程類似,但此時使用innerHTML元件保存綁定到數據欄位的INPUT標記。當所有的欄位都完成這樣的操作後,這個表就與數據控制項綁定了。因為這個頁面允許在兩個不同的數據集之間進行切換,所以需要先刪除現有的數據。function deleteCells(){ var iCell; var iCells; // unbind the table tblData.dataSrc = ''; // delete existing cells iCells = tblData.rows【0】.cells.length for (iCell = 0; iCell < iCells; ++iCell) { tblData.rows【0】.deleteCell(); tblData.rows【1】.deleteCell(); }}這個子程式只是對表解除綁定,然後在表格中遍歷所有的單元格並刪除它們。等到上述程式執行完畢,表格就只剩下空的表頭和表體行。這是一個用RDS和一些DHTML實現的簡單例子。可以容易地把其加到一個ASP包含檔案中,並把該檔案放到任何應用程式中,即使數據源不改變也可使用這種方法。這個例子的全部代碼——檔案RDSDynamicBinding.asp以及類似的其他類型的數據控制項例子,可以在Wrox站點上找到。 10.2.6 更新數據迄今為止,僅學習了在客戶端如何取到數據,但還沒有涉及如何更新客戶端數據,和將其送回伺服器。別忘了,記錄集是下線的,那么如何更新數據呢?對數據所做的任何修改只是數據控制項中本地記錄的一部分,因此為了更新伺服器必須發一條特殊的指令。然而這並不需做什麼複雜的工作,因為RDS數據控制項有兩個方法,允許我們要么取消最近對數據所做的任何修改,要么將所有修改送到伺服器。為了方便用戶,可以為此創建一些按鈕。 ONCLICK="dsoData.CnacelUpdate()">Cnacel ONCLICK="dsoData.SubmitChanges()">SaveSubmitChanges方法只將那些改動過的記錄送回伺服器,而CancelUpdate方法則取消在本地記錄集上所做的任何修改。更新和取消更新操作並不是唯一所需的。如果想增加新的記錄或刪除一條現有的記錄,怎么辦?可以使用記錄集的AddNew和Delete方法。這將增加或刪除記錄集中的記錄,然後在傳送SubmitChanges命令後,伺服器上的數據就可以被更新。 ONCLICK="dsoData.recordset.Delete()">Delete ONCLICK="dsoData.recordset.AddNew()">Add 1. 解決衝突的方法 由於與數據源下線,可能會碰到有關衝突的問題。例如在更新一條記錄並將其保存到數據存儲的時候,有人也修改了這條記錄時,會發生什麼情況? SubmitChanges方法已經提供了相應的處理衝突的方法,如果發生衝突,那么該方法將產生一個錯誤。 在調用SubmitChanges方法期間,只要其中一條記錄更新失敗,那么所有的記錄更新都會失敗。這保證了原始數據不會被部分更新。可以遍歷記錄集,並檢測記錄的Status屬性來告訴用戶哪一條記錄更新失敗了。例如,最好調用自己的updateData函式,而不只是在命令按鈕中調用SubmitChanges方法。 此時,我們知道已經發生了一個錯誤,但並不知道是哪一個錯誤,因此必須重新同步當前數據與數據存儲中的數據。使用adResyncUnderlyingValues確保只有欄位的UnderlyingValues屬性被數據存儲中的值復蓋,也就是說所做的修改是安全的(記住,修改的內容保存在Value屬性中)。可以在後面的代碼中比較當前的值與資料庫中的值。 Status可以是不同值的組合,詳見附錄。例子代碼( RDSConflicts.asp )中有一個將這些值轉換為描述性字元串的函式。 我們知道記錄有某些形式的衝突,但無法確切地知道為什麼或哪一個欄位引起了衝突。因此需要遍歷欄位檢測它們的值。 這就是UnderlyingVaule屬性發揮作用的地方。 欄位有三種值: Vaule代表新值,即經過修改的欄位值。 UnderlyingVaule代表數據存儲中存儲的欄位值。 OriginalVaule代表從數據存儲讀取後,但還沒有修改之前的欄位值。 這意味著UnderlyingVaule會保存其他用戶修改過的值,而OriginalValue是欄位原有的值。因此比較兩者之值,如果不同,則說明欄位已經被另外的用戶修改了。 可以利用所有這些錯誤信息來創建一個表格以顯示是否確實發生錯誤。例子(RDSConflicts.asp)產生的輸出結果如圖1 0 - 11所示。 這裡可以見到三種不同的值。原始值是Johnson。然後,在另一個視窗(如SQL Server Query Analyzer)中將值改為Johnson。在瀏覽器視窗,利用RDS將這個值改為Andy,並按下Save All Changes按鈕。Resync命令將資料庫中的值取出並寫入UnderlyingVaule屬性。我也對Lastname列做了相似的修改。 使用這種方法,可以看到每一個發生變化的欄位的值。由於SubmitChanges方法可以處理多個欄位,讀者可能希望為這個表增加額外的列以顯示ID欄位,這樣就可以看到是哪一個欄位更新失敗了。
無線廣播
RDS是英國BBC廣播公司開發的一種特殊的無線電廣播,稱“無線數據廣播系統”(Radio Data System),它是在調頻廣播發射信號中利用副載波把電台名稱、節目類型、節目內容及其它信息以數字形式傳送出去。通過具有RDS功能的調諧器就可以識別這些數位訊號,變成字元顯示在顯示屏上。在收到節目的同時,通過RDS可知道接收到的是那個電台,它的發射頻率,並給出該電台其餘的頻率,由此再使用“切換頻率”鈕來保證所接收的信號為最強的頻率。RDS無線數據廣播檔案可顯示接收到的節目名稱及其它資料。RDS功能可按節目類型決定取捨,尋找到符合你要求的電台。RDS還能用來自動控制接收機,使流動工作的汽車收音機一直保持最佳接收狀態,及時收到緊急交通報告,有利交通安全。 RDS除使收音機自動化、高檔化外,並在城市交通管理中發揮作用,其使用領域尚在拓展中。