監(jiān)理公司管理系統(tǒng) | 工程企業(yè)管理系統(tǒng) | OA系統(tǒng) | ERP系統(tǒng) | 造價咨詢管理系統(tǒng) | 工程設(shè)計管理系統(tǒng) | 甲方項目管理系統(tǒng) | 簽約案例 | 客戶案例 | 在線試用
X 關(guān)閉

設(shè)計合同

申請免費試用、咨詢電話:400-8352-114

AMTeam.org

設(shè)計合同

 

Scott Seely

Microsoft Corporation

2001年6月6日

簡介

我們已經(jīng)很長時間沒有在 At Your Service 專欄中與您進行交流了。為了扭轉(zhuǎn)這一局面,我們專門成立了一個小組來從事這方面的工作,小組成員包括 Matt Powell 和 Scott Seely。我是 Scott,先由我和大家來探討有關(guān)問題。不久前,Mary Kirtland 在讓我們認識一下(英文)一文中對我們進行了介紹。不過,既然以后由我們主持本專欄的工作,我們想更為詳細地介紹一下自己。

Matt 在 Microsoft 工作了 10 年以上,大部分時間是在 Microsoft 的開發(fā)人員支持機構(gòu)中工作。他堅持認為自己是一個網(wǎng)絡(luò)協(xié)議專家,因為他總是有機會對涉及 DLC、NetBIOS、Winsock、RPC、SNMP、WinInet 和 ISAPI 中的一切提供支持。相對于 Windows? 資源管理器來說,Matt 更喜歡使用 MS-DOS 提示符;在緊急情況下,甚至會使用 EDLIN 來編輯文本文件。業(yè)余時間,Matt 喜歡帶著他的一家九口去觀看西雅圖水手隊的比賽。他總是坐在第一排,就在 Ichiro 的身后觀看比賽,不停揮舞著白毛巾,瘋狂地為西雅圖水手隊吶喊助威。

如果您閱讀過本專欄以前發(fā)布的文章,您可能會注意到 James Francisco(他以前是我們小組的成員之一)曾經(jīng)提到我們已經(jīng)落后于進度表,因為一半開發(fā)人員(指我)休假回家去照顧孩子了。3 月 15 日,我去看望了我的女兒 Angeline。她的母親、哥哥和我都花了四周時間來了解我們這個新家庭成員。在那段時間中,我還為 Prentice Hall 撰寫完有關(guān) SOAP 的一書《SOAP:使用 XML 開發(fā)跨平臺 Web 服務(wù)》(英文)。它將在 2001 年 7 月底與讀者見面。除了著書之外,我還從事跨平臺開發(fā)工作。這是因為實際上,我使用過三個非 Microsoft 的 SOAP 工具包:我自己的 SimpleSOAP(英文)、Apache SOAP(英文)和 SOAP::Lite(英文)。

概述

在本專欄中,我們將討論為 Web 服務(wù)設(shè)計合同時,需要考慮哪些因素。希望您在提到 Web 服務(wù)時,不要再聯(lián)想到諸如檢索股票價格或是查看您所在城市當前的氣溫這樣的事情了。相反,您應(yīng)該將 Web 服務(wù)看作具有相當完善功能的 API 的組件。在本專欄中,我們將討論如何設(shè)計 Web 服務(wù)的接口以及滿足全球化要求。

定義 Web 服務(wù)的接口

現(xiàn)在,通過 Web 服務(wù)說明語言 (WSDL) 文件可以告知他人如何訪問和使用 Web 服務(wù)。最初引入 SOAP 時,曾出現(xiàn)過多種基于 XML 的接口說明語言 (IDL)。所有這些 IDL 識別不同的描述服務(wù)方式,并且包含一些特定于它們所依附的 SOAP 實現(xiàn)方案的項目。業(yè)界很快意識到必須進行標準化,這樣就產(chǎn)生了 WSDL。WSDL 說明了以下項目:

Web 服務(wù)可以識別的數(shù)據(jù)類型

消息架構(gòu)

Web 服務(wù)使用的交換方法(請求/響應(yīng)、單向、多播等等)

Web 服務(wù)的位置

錯誤信息

標頭信息

對 WSDL 的完整說明已超出了本文討論的范圍,不過在本文的末尾,您可以找到一些非常好的 WSDL 背景資料的鏈接。現(xiàn)在我只想集中討論如何使用以上項目來定義 Web 服務(wù)的接口。

定義接口時,首先應(yīng)考慮數(shù)據(jù)類型。應(yīng)該始終確保您的類型可以重新映射到 XML 架構(gòu)數(shù)據(jù)類型。例如,對于字符串,應(yīng)該使用 xsd:string。構(gòu)建復雜的類型時,請確保它們最終可以分解為預(yù)定義的 XML 架構(gòu)數(shù)據(jù)類型之一。例如,您可以通過電子郵件地址和業(yè)務(wù)電話號碼來定義一個聯(lián)系人。WSDL 文件的類型部分類似于以下內(nèi)容:

<definitions xmlns:s="http://www.w3.org/2001/XMLSchema"
   
xmlns:s0="
http://tempuri.org/"
   
targetNamespace="
http://tempuri.org/"
   
xmlns="
http://schemas.xmlsoap.org/wsdl/">
   
<types>
       
<s:schema attributeFormDefault="qualified"
           
elementFormDefault="qualified"
           
targetNamespace="
http://tempuri.org/">
           
<s:element name="ContactInfo">
               
<s:complexType>
                   
<s:sequence>
                       
<s:element minOccurs="1" maxOccurs="1"
                           
name="name" nillable="true"
                           
type="s0:PersonName" />
                       
<s:element minOccurs="1" maxOccurs="1"
                           
name="emailAddress" nillable="true"
                           
type="s0:EmailAddress" />
                       
<s:element minOccurs="0" maxOccurs="unbounded"
                           
name="phoneNumbers" nillable="true"
                           
type="s0:PhoneNumber" />
                   
</s:sequence>
               
</s:complexType>
           
</s:element>
           
<s:complexType name="PersonName">
               
<s:sequence>
                   
<s:element minOccurs="1" maxOccurs="1" name="first"
                       
nillable="false" type="s:string" />
                   
<s:element minOccurs="1" maxOccurs="1"
                       
name="middle" nillable="true"
                       
type="s:string" />
                   
<s:element minOccurs="1" maxOccurs="1" name="last"
                       
nillable="false" type="s:string" />
               
</s:sequence>
           
</s:complexType>
           
<s:complexType name="PhoneNumber">
               
<s:sequence>
                   
<s:element minOccurs="1" maxOccurs="1"
                       
name="areaCode" nillable="false"
                           
type="s:long" />
                   
<s:element minOccurs="1" maxOccurs="1" name="prefix"
                       
nillable="true" type="s:long" />
                   
<s:element minOccurs="1" maxOccurs="1" name="suffix"
                       
nillable="false" type="s:long" />
               
</s:sequence>
           
</s:complexType>
       
</s:schema>
   
</types>
   
...

</definitions>

正如您所看到的,所有的復雜類型最終都分解為現(xiàn)有的 XML 架構(gòu)數(shù)據(jù)類型。有了這樣的限制,其它 SOAP 實現(xiàn)方案就更有可能與您的 Web 服務(wù)進行交互。這是因為不同的平臺存在著不同的 XML 架構(gòu)實現(xiàn)方案,只要符合標準并盡量避免使用自己偏愛的個人實現(xiàn)方案,就可以增加 Web 服務(wù)的可用性。

下一步,應(yīng)考慮如何將 Web 服務(wù)的功能分解成多個因子。對 Web 服務(wù)進行編程時,應(yīng)該將相關(guān)的操作組合到單個端口中。對于收藏服務(wù),我們在設(shè)計上將其分解為三個服務(wù):

登錄:對被授權(quán)者進行身份驗證并授予他們一個訪問服務(wù)時使用的密鑰

帳戶:處理最終用戶的創(chuàng)建和收藏數(shù)據(jù)的維護事項

報表:處理報表

將功能分成相關(guān)的功能塊后,在構(gòu)建特定的功能時,Web 服務(wù)的用戶就可以很輕松地找到他們所需的功能。編程人員可以了解與特定端口有關(guān)的功能,從而使他們的工作變得更為輕松。

這些端口的實現(xiàn)一般駐留在一個對象中。在內(nèi)部,對象可以共享公共的 Helper 函數(shù)。在外部,這些對象不應(yīng)該依賴于內(nèi)部狀態(tài)。我曾觀察過新聞組,發(fā)現(xiàn)許多人在試圖傳送 SOAP 對象的指針或引用時都遭遇了失敗。為什么他們會失敗呢?因為他們設(shè)計的東西要求引用指針,但很快他們就會意識到 SOAP 不允許這樣做。

如果您陷入了困境,我們向您介紹一個很好的解決方法:使用 in/out 參數(shù)。無論對象是 in、out 還是 in/out 參數(shù),它必須能將自己的狀態(tài)寫入 XML。當您指定所需的對象部分時,請分析一下功能真正需要什么數(shù)據(jù),并且只需要該信息。這可能會產(chǎn)生巨大的差異,因為在網(wǎng)絡(luò)上傳輸數(shù)據(jù)可能比整個串行化過程花費的時間更多。消息越小,到達目的地所需的時間也就越少。

您可能還希望確保能夠監(jiān)視來回傳送的參數(shù)。如果使用可以生成 WSDL 的工具(例如 .NET 運行時或 SOAP Toolkit v2 WSDLGEN.EXE 工具),您可能不會意識到自己正在浪費帶寬。在構(gòu)建解決方案時,請花一些時間來了解生成的 WSDL 看起來像什么??纯词欠窨梢哉业綔p少消息往返次數(shù)的位置。例如,Visual Basic? COM 對象中作為 ByRef 發(fā)送的任何參數(shù)(如果您不指定,它們將都是 ByRef)都是一個 in/out 參數(shù)。如果使用該對象,但在返回之前不對它進行修改,則應(yīng)該將該參數(shù)更改為 ByVal。同樣地,請檢查 C++ 對象的 IDL 文件,并確保參數(shù)進行了相應(yīng)的限定。

大多數(shù)情況下,Web 服務(wù)使用了請求/響應(yīng)(即傳統(tǒng)的 RPC)??梢酝ㄟ^忽略 operation 的 output 元素來指定單向。

請求/響應(yīng):

<operation name='DeleteFavorite' parameterOrder='key Username FavID'>
   
<input message='wsdlns:Account.DeleteFavorite' />
   
<output message='wsdlns:Account.DeleteFavoriteResponse' />

</operation>

單向:

<operation name='DeleteFavorite' parameterOrder='key Username FavID'>
   
<input message='wsdlns:Account.DeleteFavorite' />

</operation>

單向消息只是忽略了輸出消息。如果有必要,請忽略“輸出消息”。這樣做可以減少等待的時間,并且可以使服務(wù)運行得更快一些,因為客戶程序不再等待返回的消息。

因為 WSDL 是 IDL,WSDL 端口代碼的唯一要求是它必須正確地響應(yīng)任何 SOAP 請求。這對您意味著什么呢?假定我們正在使用一個客戶端應(yīng)用程序,它要和三個處理訂單的服務(wù)器進行通信。其中一個服務(wù)器可以處理家具訂單,另一個處理書籍訂單,第三個則處理 DVD 訂單。假定這些系統(tǒng)之間的唯一差別是項目的數(shù)據(jù)庫,則我們可以使用相同的客戶程序來訪問不同的服務(wù)。唯一的差別應(yīng)該是服務(wù)的端點。(這是 UDDI 所依賴的概念之一。)WSDL 的 SOAP 綁定通過使用 soap:address 元素來做到這一點。

<service name='Account' >
   
<port name='AccountSoapPort' binding='wsdlns:AccountSoapBinding' >
      
<soap:address location='http://coldrooster.com/ssf/account.asp' />
   
</port>

</service>

許多能識別 WSDL 的工具包允許在讀取文件后更改端點。如果知道實現(xiàn)端口的其它服務(wù)的位置,或者使用 UDDI 服務(wù)器來獲取類似的信息,則可以使用同一個客戶程序與不同的端點進行通信。

如果花費一些時間來考慮 SOAP 接口,您的 Web 服務(wù)將可以從任何計算機上進行訪問。如果多個資源提供了相同的服務(wù),公共接口將允許單個客戶程序訪問不同的 Web 服務(wù)。使用自動生成 WSDL 的工具設(shè)計這些應(yīng)用程序時,請花費一些時間來查看生成的 WSDL 并確保只發(fā)送絕對必要的信息。因為對于簡短的操作,您會發(fā)現(xiàn)網(wǎng)絡(luò)將成為瓶頸。

Web 服務(wù)的全球化

還應(yīng)該考慮訪問 Web 服務(wù)的類型。世界各地的用戶可能都在使用該服務(wù),這對您意味著什么呢?

您可能會遇到數(shù)據(jù)存儲和傳輸?shù)膯栴}。如果您的服務(wù)接受字符串數(shù)據(jù),請確??梢越邮堋鬏敽痛鎯H字母表(例如日語、西里爾語、阿拉伯語等等)。有了收藏服務(wù),我們可以通過要求服務(wù)接受 UTF-8 和 UTF-16 編碼的 XML 來處理該問題。Microsoft? SOAP Toolkit v2 可以做到這點??紤]后端系統(tǒng)時,您還應(yīng)該考慮大字符集問題,即使用支持 Unicode 的字符串類型和數(shù)據(jù)存儲器。對于收藏服務(wù),我們使用 Visual Basic,因為它可以在本地處理 Unicode 字符串。在存儲器端,我們使用 nchar 和 nvarchar 數(shù)據(jù)類型在 Microsoft? SQL Server 中存儲所有的字符串。正如您可以看到的,挑選合適的工具可以更輕松地滿足國際化這個方面的要求。

您還需要考慮如何分發(fā) Web 服務(wù)文檔。由于大多數(shù)開發(fā)人員可以使用英語進行讀寫,因此只要提供規(guī)范的英文文檔,您就可以贏得巨大的訪問量。在這些文檔中,不要使用俚語,而應(yīng)該使英文盡可能簡單易懂。要吸引其它國家中的用戶接受您的服務(wù),您可能需要考慮使用開發(fā)人員的母語提供文檔。

返回 SOAP 錯誤時,您可能需要考慮允許被授權(quán)者為 Fault.Description 成員指定首選語言。錯誤數(shù)適中將有助于服務(wù)的最終用戶進行查看。我們曾想提供一些以特定語言表述的錯誤字符串,但最終決定不這樣做。(我聽說 Project Lucy 正在考慮對錯誤字符串進行翻譯,可能在今年的晚些時候他們的小組將會就這一問題進行討論。)相反,我們編寫了有關(guān)文檔,在其中指定了一些 Fault.Code 值,Web 服務(wù)提供的函數(shù)會返回這些值。這樣將允許編程人員編寫使用收藏服務(wù)來處理自己的錯誤和本地化的應(yīng)用程序。

還應(yīng)該考慮:當 Web 服務(wù)不僅在您所在地區(qū)而且在其它地區(qū)被公眾接受時,應(yīng)該做些什么。此時,Cold Rooster 的服務(wù)都集中在華盛頓州的雷蒙德。美國之外的用戶必須通過橫跨大洋的 Internet 鏈接來使用服務(wù)。如果這樣的用戶很多,我們必須考慮在世界的其它地區(qū)部署 Web 服務(wù),以便用戶獲得更快的響應(yīng)時間。使用全球分布的服務(wù)器來處理請求以后,又出現(xiàn)了新的問題。其中一個是:擴展 Web 服務(wù)時,必須考慮如何分發(fā)用戶數(shù)據(jù)。

對于收藏服務(wù),以下列舉了可能出現(xiàn)的一些新問題:

被授權(quán)者希望能夠訪問所有 Web 服務(wù)器上的 Web 服務(wù),因此我們必須提供在數(shù)據(jù)中心之間同步數(shù)據(jù)的方法。

無論最終用戶處于哪個位置,他們都希望數(shù)據(jù)可以傳送給他們。這意味著我們必須強制被授權(quán)者記住所聯(lián)系的哪個數(shù)據(jù)中心可以獲取最終用戶數(shù)據(jù),或者將所有的用戶數(shù)據(jù)傳播到所有數(shù)據(jù)中心。

當審計事件在全球發(fā)生時,我們?nèi)绾翁幚韺徲嬋罩??最有可能的是:在某個位置的某個數(shù)據(jù)庫中存儲所有的審計數(shù)據(jù),并簡單地將對該數(shù)據(jù)源的請求排隊,以避免任何延遲問題。

我們必須設(shè)計規(guī)則,解決全球各地分散的數(shù)據(jù)中心之間的更改沖突。例如,被授權(quán)者可能在兩個不同的服務(wù)器上更改了管理聯(lián)系人數(shù)據(jù),我們必須要提出如何處理這種沖突的規(guī)則。

與全球化有關(guān)、但易于忽略的最后一個問題是確定如何接受付款。您是允許用戶使用任何貨幣付款呢,還是要求他們使用您的本地貨幣付款?全球化這方面的問題可能非常復雜,我們現(xiàn)在暫時將它放入思想庫中,如果讀者感興趣,我們將在以后的文章中進行討論。

總結(jié)

設(shè)計 Web 服務(wù)時,要考慮 Web 服務(wù)是如何使用的。如果在工具所生成的 WSDL 文件方面花費一些時間,可以優(yōu)化它在網(wǎng)絡(luò)上的性能。這些文件將有助于找出在何處傳送大量數(shù)據(jù)會對總體吞吐量造成不良影響。同時,避免將所有功能都放置在一個存儲桶中,除非這樣做是非常必要的。在一個端口上將相關(guān)的功能歸集在一起。

考慮全球化問題時,應(yīng)盡量使設(shè)計的程序適用于處于不同地區(qū)的用戶。預(yù)料到用戶可能使用多種語言。對于收藏服務(wù),我們進行了測試,確保可以為大字母表的語言(例如中文)存儲字符串。測試您的 Web 服務(wù)時也應(yīng)該這么做。標識可能不在前 128 個 ASCII 字符范圍內(nèi)的所有字符串,并確??梢源鎯吞崛≈形?、阿拉伯語以及其它一些字母表的字符串。這將檢查您處理 Unicode 字符串的能力。

有關(guān) WSDL 的更多知識,請查閱以下文章:

WSDL 背景資料:

WSDL 入門(英文)

Yasser Shohoud 撰寫的 WSDL 簡介(英文)

發(fā)布:2007-03-24 18:00    編輯:泛普軟件 · xiaona    [打印此頁]    [關(guān)閉]
相關(guān)文章:
上海OA系統(tǒng)
聯(lián)系方式

成都公司:成都市成華區(qū)建設(shè)南路160號1層9號

重慶公司:重慶市江北區(qū)紅旗河溝華創(chuàng)商務(wù)大廈18樓

咨詢:400-8352-114

加微信,免費獲取試用系統(tǒng)

QQ在線咨詢