国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

在運行時使用 UDDI (微軟)

2024-07-21 02:21:57
字體:
來源:轉載
供稿:網友

在運行時使用 uddi
karsten januszewski
microsoft corporation
2001 年 12 月

摘要:本文概述了在運行時使用 uddi,討論了 uddi(公共注冊表和 uddi 服務在 microsoft windows .net server 中提供)如何用作 web 服務的基礎結構以支持客戶端應用程序。

目錄

  • 簡介
  • uddi 運行時基礎結構
  • 示例方案
  • 創建 web 服務:c# .net .asmx
  • 使用 web 服務:c# windows 窗體 .net 客戶端
  • 其他方案
  • 總結

簡介


uddi(通用說明、發現和集成)通常稱為 web 服務的“黃頁”。雖然黃頁這一類比對于幫助理解很有用,但它不能完整體現 uddi 是如何并入基于 web 服務的軟件體系結構中的。黃頁類比只涉及 uddi 的設計時用法,即通過基于關鍵字、類別或接口的搜索來查找和使用 web 服務的功能。從設計時角度來看,黃頁類比十分準確:就象黃頁將企業及其電話號碼分類并編成目錄一樣,uddi 將提供者及其 web 服務分類并編成目錄。開發人員可以在 uddi 中查找 wsdl 文件和入口點,然后將這些 web 服務并入客戶端應用程序。
不過,uddi 不僅僅提供設計時支持。黃頁類比并沒有提及 uddi 如何支持運行時。發現過程結束后,uddi 將扮演一個很重要的角色。在運行時通過編程方式查詢 uddi 這一功能使 uddi 可以用作構建可靠而穩固的 web 服務應用程序的基礎結構。

uddi 運行時基礎結構


將 web 服務集成到客戶端應用程序中后,需要考慮可能會遇到的問題,其中一個關鍵問題是無法預測或檢測提供 web 服務的提供者的故障,或者從故障中恢復。如果 web 服務出現故障,客戶端應用程序可以采取什么措施?應用程序如何適當且動態地從失敗的 web 服務調用中恢復?
同樣,從 web 服務提供者的角度看,web 服務的所有者如何動態更新更改內容?我們需要考慮將 web 服務移到新服務器的情況。如何將此更改通過有效方式通知到 web 服務的客戶端?所有者如何在運行時分發此信息,而不會導致 web 服務的所有客戶端中斷?
在上述情況下,uddi 在提供基礎結構以支持運行時 web 服務方面能夠扮演十分重要的角色。uddi 通過定義調用規則來解決這些“服務質量”問題,該調用規則包括緩存綁定信息(如 web 服務的入口點)以及針對此特定實現方式的其他參數。發生故障時,客戶端可以發出運行時 uddi 查詢,用最新信息刷新緩存的信息。
上述規定的模式如下:
  1. 在 uddi 中查找 web 服務。使用此 web 服務(以 uddi tmodel 表示)的 wsdl 文件以及入口點和其他配置信息的實現細節,所有這些信息都包含在 uddi bindingtemplate 中。
  2. 為特定的 web 服務準備一個客戶端應用程序。在客戶端應用程序中,緩存 web 服務的唯一 bindingkey,以便在首次使用該應用程序時,從 uddi 檢索所需的所有信息。
  3. 當應用程序調用遠程 web 服務時,使用從 uddi web 注冊表獲得的緩存數據。
  4. 如果調用失敗,則使用 bindingkey 值和對 uddi 注冊表的 get_bindingtemplate api 調用以獲取新的綁定信息。
  5. 對新舊信息進行比較:如果不同,則重試失敗的調用。如果重試成功,則用新數據替換緩存的數據并存儲新數據以便以后調用。不過,如果返回的綁定信息相同,則提供者不進行任何更新,且應用程序將發生錯誤。同樣,如果有新的綁定信息,但調用仍然失敗,應用程序也會發生錯誤。

從 web 服務提供者的角度來說,提供者應當知道何時可以更新該 web 服務的 uddi 項。當 web 服務的提供者需要將流量重定向到新位置或者需要備份系統時,提供者只需激活備份系統,然后在 uddi 注冊表中更改入口點。此方法稱為失敗時重試,為客戶端提供了一種在運行時從故障中恢復的機制。

示例方案


我們可以看一個示例,以了解此模式的工作原理。此示例方案涉及的是一家虛構公司的方案,該公司需要向其內部部門提供實時銷售數據。因此,此 web 服務不能公開,而只在防火墻內部使用。
首先,我們需要一個 web 服務。在這種情況下,我們將提供一個非常簡單的 web 服務,它只支持 getsalestotalbyrange 一種方法,這種方法使客戶端能夠獲取一定日期范圍內實時銷售數據的瞬態圖。
接下來將創建使用此 web 服務的客戶端。我們將客戶端配置為可以緩存入口點和 bindingkey 信息,并為客戶端設置一種機制,以便在發生故障時從 uddi 注冊表刷新客戶端緩存。

創建 web 服務:c# .net .asmx


microsoft .net 框架大大簡化了 web 服務的編寫工作。在本例中,我們將創建一個簡單的 web 服務,它只包含 getsalestotalbyrange 一種方法,該方法使用兩個日期作為輸入參數,并返回兩個參數。下面是一個實現了此目的的 .asmx 頁,salesreport.asmx:
<%@ webservice language="c#" class="salesreportusa.salesreport" %>using system;using system.web.services;namespace salesreportusa{   [webservice(namespace="urn:mycompany-com:salesreport-interface")]   public class salesreport : system.web.services.webservice   {      [webmethod]      public double getsalestotalbyrange ( system.datetime startdate, system.datetime enddate )      {         return 5000.00;      }      }} 

此頁應添加到虛擬目錄中。要使客戶端示例工作,請創建一個名為 salesreportusa 的虛擬目錄 (http://localhost/salesreportusa/salesreport.asmx)。請注意,此 web 服務始終返回 5000.00 作為返回值。(要是銷售報表能夠有這樣的可預見性就好了!)真實的應用程序應當使用數據庫調用來檢索此信息。對于本示例,只需要一個硬編碼的值。
部署此 web 服務的下一步是在 uddi 注冊表中注冊該服務。此 uddi 注冊表是一個內部 uddi 服務器,公開此 web 服務沒有什么意義。microsoft 通過 microsoft® windows® .net server 提供本地 uddi 服務。有關此功能的詳細信息,請參閱 windows .net server(英文)web 站點。如果沒有安裝 microsoft .net server,您可以使用 microsoft uddi 軟件開發包 (sdk)(英文)在本地計算機上安裝 uddi。
可以通過兩種方式在 uddi 中注冊 web 服務:可以使用 web 用戶界面注冊,或者使用 uddi sdk 通過編程方式注冊 web 服務。sdk 使用起來非常方便,您可以參閱使用 uddi 的 web 服務說明和發現專欄中發布的代碼示例。無論使用哪一種方法,都需要先將 web 服務的 wsdl 文件注冊為 tmodel。uddi tmodel 是 xml 實體,用于表示接口和抽象的元數據,因此,wsdl 文件表示為 tmodel。然后,您需要將 web 服務的入口點注冊為 bindingtemplate。uddi bindingtemplate 是 xml 結構,用于表示有關給定 web 服務的實現細節。有關 uddi 架構及其與 wsdl 的關系的詳細信息,請參閱 http://www.uddi.org(英文)和 uddi“最佳實踐”文檔 using wsdl in a uddi registry 1.05(英文)。
以下是使用 uddi 服務完成上述步驟后得到的 uddi bindingtemplate 結構的示例。請注意,servicekey、bindingkey 和 tmodelkey 都是由 uddi 生成的,并且對于我們保存的實體來說是唯一的。由其他 uddi 注冊表生成的關鍵字會有所不同。
<bindingtemplate servicekey="ef25102d-2171-454c-ade9-3dd7a4a914ee"       bindingkey="f46fced9-2b8a-4817-b957-f8d8aca0a2f9">   <accesspoint urltype="http">      http://localhost/salesreportusa/salesreport.asmx   </accesspoint>   <tmodelinstancedetails>      <tmodelinstanceinfo tmodelkey=            "uuid:b28fe40a-ea62-4657-88d5-752d8a6cdf77" />   </tmodelinstancedetails></bindingtemplate>

在上述結構中,我們突出顯示了此 web 服務的入口點和 bindingkey。這對于客戶了解這兩部分的信息非常重要。此外,如果某個客戶端需要獲取此 web 服務的 wsdl,則可以使用 tmodelkey 查詢 uddi 以獲取該 tmodel。

使用 web 服務:c# windows 窗體 .net 客戶端


現在,我們可以轉換一下角色,看看應用程序的客戶端部分。在設計時,我們也許可以在 uddi 中找到此 web 服務。我們將下載相應的 wsdl 文件并使用 microsoft visual studio® .net 的 add web reference(添加 web 引用)或 wsdl.exe 生成一個代理類。(wsdl.exe 是一個命令行工具,屬于 microsoft .net 框架 sdk 的一部分。)
現在可以開始編寫客戶端應用程序中的邏輯。在本例中,它是稱為 salesreportclient.exe 的 c# windows 窗體應用程序,允許用戶查詢銷售報表信息。
首先,需要將 uddi .net sdk 類添加到項目中,可以下載這些類。(microsoft uddi sdk 版本 1.5.2 [英文] 與 visual studio .net beta 2 兼容;microsoft uddi .net sdk beta 版本 1.75 [英文] 與 visual studio .net release candidate 兼容。) using 聲明如下:
using system;using system.drawing;using system.collections;using system.componentmodel;using system.configuration;using system.windows.forms;using system.data;using microsoft.uddi;using microsoft.uddi.binding;

然后,需要將 uddi 服務器的入口點存儲在此 web 服務所在的位置(畢竟,uddi 本身就是一個 web 服務)。要執行此操作,需要為此 .exe 可執行文件創建一個應用程序配置文件,用于存儲 uddi 服務器的位置。web 服務的 bindingkey 也將存儲在此配置文件中。通過在 .net 中使用 xml 配置文件,您可以添加任意數量的 appsetting,應用程序可以通過集合獲取。
<?xml version="1.0" encoding="utf-8" ?><configuration>   <appsettings>      <add key="uddi_url" value="http://localhost/uddi/api/inquire.asmx" />      <add key="bindingkey" value="f46fced9-2b8a-4817-b957-f8d8aca0a2f9" /></appsettings></configuration>

在此示例中,我們指向駐留在自己的計算機上的 microsoft uddi developer edition 服務器。uddi_url 也可以是公共 uddi 節點之一,或者是駐留在企業內部的 uddi 注冊表。使用配置文件 app.config 的命名規則來保存此文件。編譯應用程序后,配置文件將被放在 /bin 目錄中,并使用它自己的 .exe 名稱命名。
剛剛完成的這個步驟(添加有關 web 服務的配置信息),與 visual studio .net 如何在添加到項目的每個 web 引用上公布 url behavior 屬性并沒有什么不同。通過將該屬性更改為 dynamic,visual studio .net 可以創建包含 web 服務入口點的配置文件。上述操作通過提供在運行時重新查詢 uddi 的功能,進一步擴展了此概念。因此,配置文件包含了 uddi 節點的入口點和 web 服務的 bindingkey。
現在,我們可以開始對應用程序本身進行編碼。首先需要創建一個文本框、一個標簽、一個按鈕和兩個日期時間選擇器。然后建立一些全局變量:
   //應用程序的一些變量   private string inquiryurl = null;   private string bindingkey = null;   private string accesspoint = null;   private bindingtemplate bt;   private double salesfigure = 0;

窗體被實例化以后,我們需要初始化以下變量:
         public form1()   {      //      //windows 窗體設計器支持所必需      //      initializecomponent();      //從配置文件導入變量      inquiryurl = configurationsettings.appsettings["uddi_url"];      bindingkey = configurationsettings.appsettings["bindingkey"];      bool initcache = refreshcachefromuddi();      if ( initcache == true ) accesspoint = bt.accesspoint.text;   }

refreshcachefromuddi() 函數用于查詢 uddi 服務器以查找入口點。使用 uddi sdk 執行 uddi api 調用 (getbindingdetail),將 bindingkey 作為參數傳遞。
   private bool refreshcachefromuddi()   {      //使用 uddi sdk,設置 uddi 入口點      inquire.url = inquiryurl;      //創建 get_bindingdetail uddi api 消息      getbindingdetail gbd = new getbindingdetail();      //添加 bindingkey      gbd.bindingkeys.add( bindingkey );      try   {         bindingdetail bd = gbd.send();         //如果成功,則使用返回集合中的第一個模板         //更新 bindingtemplate 對象         bt = bd.bindingtemplates[0];         return true;      }      catch (exception err)      {         textbox1.text += err.message;         return false;      }   }

在應用程序運行期間,我們將入口點的位置放在變量中。如果用戶要重新啟動應用程序,它將在 uddi 中重新查詢入口點,因此應用程序始終擁有對 web 服務的最新更改。如果需要,可以將這些數據緩存在文件系統或數據庫中。
接下來,需要創建調用 web 服務自身的函數:
      private bool invokewebservice()      {         localhost.salesreport sr = new localhost.salesreport();         //為代理類設置入口點         sr.url = accesspoint;         try         {            salesfigure = sr.getsalestotalbyrange( datetimepicker1.value,                datetimepicker2.value );                        label1.text = "選定日期的銷售圖表:$" +                salesfigure.tostring();            textbox1.text += "web 服務調用成功!";            return true;         }         catch (exception err)         {            textbox1.text += err.message;            return false;         }      }

最后,用戶單擊按鈕時,應用程序將嘗試調用 web 服務。
   private void button1_click(object sender, system.eventargs e)   {      cursor.current = cursors.waitcursor;      //嘗試調用 web 服務      bool webservicesuccess = invokewebservice();            //如果失敗,則查詢 uddi      if ( webservicesuccess == false )      {         textbox1.text += "web 服務失敗。重新查詢 uddi             以獲取新的入口點。/n/n";         bool uddisuccess = refreshcachefromuddi();                  //重新查詢 uddi 成功,         if ( uddisuccess == true )         {                        //將原入口點與新入口點進行比較            //確定是否有所變化            if ( accesspoint.equals( bt.accesspoint.text ) == false)            {               //如果入口點不同,則一定是新的               //重設變量               accesspoint = bt.accesspoint.text;               //并嘗試再次調用 web 服務               webservicesuccess = invokewebservice();                              //無法使用新信息調用 web 服務                   new info                if ( webservicesuccess == false )               {                  textbox1.text += "web 服務再次失敗。uddi 中已更新                     的入口點無效!/n/n";               }            }            else            {               textbox1.text += "uddi 未提供新信息。/n/n";            }         }         else         {            textbox1.text += "uddi 刷新失敗。/n/n";         }      }   }

請注意如何在運行時為 web 服務代理類設置入口點。因為所有代理類都是從 system.web.services.protocols.soaphttpclientprotocol 中衍生出來的,所以代理類會公布一系列屬性,.url 屬性就是其中之一。設置此屬性使我們能夠在運行時指定入口點。然后,我們可以通過線路發送 soap 請求。如果沒有發生異常,則表示一切正常并且從 web 服務返回的數據顯示在窗體中。但如果確實發生異常,此函數返回“假”,調用代碼將嘗試從 uddi 刷新入口點,以重新使用 refreshcachefromuddi() 函數。
重新查詢 uddi 之后,我們會將 uddi 返回的入口點與原入口點進行比較。如果入口點相同,則提供者尚未使用新信息更新 uddi,我們所能做的只有嘗試與 web 服務的提供者聯系,告訴他們 web 服務不響應。但是,如果從 uddi 檢索到的入口點不同,則可以嘗試再次調用 web 服務。
為模擬故障,可以更改 web 服務的名稱。嘗試運行應用程序。然后,用 web 服務的新名稱更新 uddi 項。再次運行應用程序。應用程序將在 uddi 中找到新的入口點,成功查詢新服務,然后保存此信息。如果您完全關閉應用程序,再重新打開,則第一次嘗試時應該能夠再次調用 web 服務。

其他方案


這個“失敗時重試”示例討論的是 uddi 可在運行時用作 web 服務客戶端的支持基礎結構。在以后的專欄中,我們將討論其他方案,包括:
  • 優化入口點查找 - 可能有多個 web 服務支持駐留在不同服務器上的公共接口,這些服務器又位于不同的物理位置。客戶端應使用最近的 web 服務。通過運行時 uddi 查找,客戶可以根據不同服務的地理分類或與該實現關聯的其他元數據來確定最佳入口點。
  • 基于公共接口聚合數據 - wsdl 中可能定義了一種用于搜索目錄的標準 web 服務接口。該行業的很多供應商都可以實現 web 服務接口,并在 uddi 中發布入口點。在運行時,客戶端應用程序可以動態搜索這些入口點并發出查詢以收集這種編錄數據。通過這種方式,輪詢應用程序可以利用運行時 uddi 數據。

此外,我們還將討論如何優化 wsdl 文件,使其真正充當接口說明文件。

總結


uddi 提供了重要的運行時功能,可以集成到應用程序中以創建更強壯的動態客戶端。通過將 uddi 用作 web 服務體系結構中的基礎結構,可以編寫更加可靠的應用程序。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 察雅县| 孝感市| 哈密市| 红河县| 甘洛县| 武宁县| 昭通市| 临清市| 孙吴县| 喀喇沁旗| 阜南县| 息烽县| 安达市| 武定县| 新乡市| 永平县| 昌黎县| 民丰县| 无为县| 施秉县| 永仁县| 和林格尔县| 榕江县| 伊宁市| 饶阳县| 平江县| 台山市| 曲麻莱县| 柳江县| 涪陵区| 禹州市| 扶余县| 育儿| 定陶县| 山东| 乌兰浩特市| 盐山县| 南通市| 遵化市| 霍州市| 甘孜|