本文章是由機器翻譯。

預測: 多雲

在 Windows Azure 的 AppFabric 服務匯流排: 主題

約瑟夫 Fultz

 

本文根據 Windows Azure AppFabric CTP 年 6 月更新。本文包含的所有資訊均有可能變更。

它是 Windows Azure 服務匯流排功能並沒有真正取得多支援從你我同事之間沒有密碼。不過,Windows Azure AppFabric CTP 年 6 月更新,Microsoft 已經將最後新增不足,無法將服務匯流排從什麼我視為不比真正有用的技術版面配置區更多的功能。AppFabric 服務匯流排現在提供訊息技術的基本項目的我在這裡,是主題,豐富的發佈與訂閱功能。我會把焦點放在主題上在此文件] 和 [繪圖],當我從 [我的零售產業經驗來看看如何使用的技術,以利於進行 inter-store 的存貨檢查執行,因此通常引起。

您是否已經購買某個商品,並找到就已總銷售量的最後一個,或您想要的項目會以某種方式弄吗?在這種情況下,銷售員通常會進入 POS 系統,並檢查庫存在鄰近的儲存區。往往並不,檢查庫存計數會保存在中央資料庫或企業資源規劃 (ERP) 系統的某種類型的針對,顧客通常會檢查使用她善意的知識的鄰近的儲存區的存放區編號。通常,資料是有點過時,因為交易記錄檔及其他資料時,其具有只在結束日期處理時的一部分更新會上載並由公司的系統處理。

更理想的案例就是擲存放區可以隨時回有關產品的可用性,到 ether 的要求,並將鄰近的儲存區會回應,指出是否保留它。這是什麼我要設定使用 Windows Azure AppFabric 服務匯流排,如下所示圖 1


圖 1] 的存貨檢查訊息

主題會提供持久的機制,讓我個別主題最多 2000 「 訂閱者 」 發送出內容。「 訂閱者 」 的限制是令人遺憾,因為它可能會強制 (就像我將說明的那一個) 解決方案架構以某種方式建立主題中的 [區段以避免。例如,而非美國存貨檢查主題的 「 訂閱者 」 篩選區域,我可能需要建立 SouthCentral 美國清查檢查的主題,進一步篩選到特定的本機子目錄。繼續與該一項警告,我將會執行我單一存貨檢查主題,我可以保證我不會有個以上的少量加盟權位置在我的 wonderland。

 

 

收到的訊息

您可以下載 Windows Azure AppFabric CTP 年 6 月更新的 bit.ly/p3DhAU,並尋找管理入口網站在 portal.appfabriclabs.com。我會存取管理入口網站擷取幾項我需要我的程式碼中使用的資訊 (請參閱圖 2)。


圖 2] 從 Windows Azure 的 AppFabric 管理入口網站取得資訊

我必須先擷取服務閘道、 預設發行者 (永遠中的 「 董事長 」 CTP) 以及預設機碼。因為我需要這些在我的範例,我會在物件的範圍內建立:

private string sbNamespace = "jofultz";
private string issuerName = "owner";
private string issuerKey = "25vtsCkUPBtB39RdiBbUtCQglYRPOdHHC4MvX5fvxxxx";

我將我的函式中使用這些變數,來建立該主題,然後再將郵件張貼到主題。沒有人想要使用它,或誰不允許使用用戶端程式庫的平台上部署的其他介面。因為我在建立 Windows 用戶端,我要使用的程式庫。若要這樣做,我需要將參考加入至 Microsoft.ServiceBus、 Microsoft.ServiceBus.Message 和 System.ServiceModel,如所示圖 3


圖 3 加入的參考

完成後,直接簡潔的程式碼,就只會需取得設定主題:

SharedSecretCredential credential =
  TransportClientCredentialBase.CreateSharedSecretCredential(
  issuerName, issuerKey);
 
Uri sbUri = ServiceBusEnvironment.CreateServiceUri(
  "sb", sbNamespace, String.Empty);
ServiceBusNamespaceClient sbNSClient =
  new ServiceBusNamespaceClient(sbUri, credential);
Topic newTopic = sbNSClient.CreateTopic(topicName);

什麼會成為重要我啟動了擲回訊息是以篩選的郵件,並取得只根據區域的接收位置相關的存放區的能力。 API 支援相互關聯與訂閱識別碼為一等公民,但我要篩選使用我的資料並將要求的內容為基礎的篩選器的知識。 因此,我想地理上關閉的存放區,來尋找並回應其他人的要求根據區域的庫存。 在此同時,我必須先確認它自己的要求並不會挑選原始的存放區。 讓原始的存放區,以篩選出自己的主題上的要求,要求將包含的項目、 在其中進行工作時查詢,該區域和 RequesterID 的 SKU:

[Serializable]
class InventoryQueryData
{
  public string Region;
  public string ResponderID;
  public string RequesterID;
  public string Sku;
  public int Count;
}

請注意我已經加入至類別的 [序列化] 屬性。 您也可以將屬性標記為 DataMembers,使用 DataContract,但重點是我想要傳送至主題的任何型別必須是可序列化的。

我已經建立一個簡單的表單,讓我輸入 SKU 的任意字串,並從張貼儲存區清單中選取。 我的 [查詢] 按鈕後的程式碼看起來類似的程式碼,來連線,並建立主題和類似於一般的建構函式中所示,尋找當處理訊息的 Api, 圖 4

圖 4 取得的資料值

// Assign data values.
InventoryQueryData data = new InventoryQueryData();
data.Sku = txtSKU.Text;
data.StoreID = cboStore.SelectedText;
data.Region = cboStore.SelectedValue.ToString();
 
Uri sbUri = ServiceBusEnvironment.CreateServiceUri("sb", sbNamespace, string.Empty);
SharedSecretCredential credential = TransportClientCredentialBase.CreateSharedSecretCredential(issuerName, issuerKey);
 
MessagingFactory msgFactory = MessagingFactory.Create(sbUri, credential);
TopicClient topicClient = msgFactory.CreateTopicClient(topicName);
MessageSender MsgSender = topicClient.CreateSender();
 
BrokeredMessage msg = BrokeredMessage.CreateMessage(data);
// Add props to message for filtering.
msg.Properties["Region"] = data.Region;
msg.Properties["RequesterID"] = data.RequesterID;
 
msg.TimeToLive = TimeSpan.FromSeconds(60);
 
MsgSender.Send(data);

有兩件事来注意。 首先,我已將新增需要的 BrokeredMessage.Properties 集合篩選的名稱 / 值組。 其次,一種執行階段維護,提供了 TimeToLive (TTL) 值為 60 秒,應該將訂閱主題取得太備份。 當然,您通常需要更多的資訊的方法來挑選 TTL,但我圖如果要求不連接任何 「 訂閱者 」 在這段期間,原因可能是太長沒有客戶那裡等待。 此外,這只是。

任何傳送到匯流排的郵件是有 factory 方法 CreateMessage BrokeredMessage 的形式。 這只會包裝入 BrokeredMessage 型別,其中包含所有的功能完整的郵件系統所需的建構執行個體的資料。

有了這個我有所有我必須逃的訊息,存貨檢查主題的 「 訂閱者 」,現在我會先擷取訊息,並回應 [訂閱] 用戶端的設定。

點一下 [主題] 資料流和回應

我的位置中的用戶端,我已經準備好傳送穩定的資料流的要求,但野生 ether 中的權限,這將會比讓位元遺失。 我建立一個 Windows Form 應用程式,並重複使用 XML 存放區清單,並從第一個 (寄件者) 應用程式 InventoryQueryData。 我需要建立唯一的訂閱,每個用戶端接聽的主題。 這可以足以輕鬆藉由組合訂閱名稱與我想要接聽的存放區號碼。 我的小測試應用程式可讓我從下拉式方塊中,選取存放區號碼,因此我只是為了建立唯一的訂閱名稱加到基底的訂閱名稱值。 請務必確定每個用戶端都有唯一的訂閱。 兩個或多個使用相同的訂閱將會建立競爭情形其中這些 「 訂閱者 」 的訊息和接收並刪除第一個會競爭使用會贏得遊戲:

Topic invTopic = sbNSClient.GetTopic(topicName);
SubscriptionName = "InventoryQuerySubscription" + this.cboStore.Text;
SqlFilterExpression RegionFilter = new SqlFilterExpression("Region = '" +
  cboStore.SelectedValue + "' AND RequesterID <> '" + cboStore.Text + "'");
 
Subscription sub = invTopic.AddSubscription(SubscriptionName, RegionFilter);

當我新增訂閱至主題時,我也可以傳遞,篩選器中,讓每個儲存區接收只庫存核取的要求自己的區域。 請注意您可以開發自己的 FilterExpression 型別,基底型別,但 API 中包含四類應涵蓋大部分的情況下,特別是如果一起使用: CorrelationFilterExpression,MatchAllFilterExpression,MatchNoneFilterExpression 和 SqlFilterExpression。 我使用 SqlFilterExpression,它可以讓我輕鬆地 instinctively 撰寫郵件取得德州區域,例如,這個運算式並排除來自我的存放區的訊息:

"Region = '[Region]' AND RequesterID <> '[StoreID]'"

我只需要篩選,傳入的要求,但在某些情況下我無法理論上 「 修正 」 的方式,在使用 RuleDescription,說,合併的 SqlFilterAction 與 SqlFilterExpression 上的資料。 前者會識別的訊息,我目標,而後者定義應該採取的動作。 適用於 [收件者] 和 [匯流排兩端的資料必須 massaged 成通過無法或不會變更時,這種功能相當有用。

一旦將訂閱設定最多,它會維持用戶端關閉,即使。 這是最適合這種情況。 我只是要建立 SubscriptionClient,每次我開始監視,並將會加入至現有的連線。 不過,不是每個人都想該行為。 我可以想像您要移除訂閱,用戶端關閉時的情況下:

SubscriptionClient subClient = msgFactory.CreateSubscriptionClient(
  topicName, SubscriptionName);
MessageReceiver msgReceiver = subClient.CreateReceiver(ReceiveMode.ReceiveAndDelete);
msgReceiver.Open();

請注意,在 CreateReceiver 的呼叫中我已將 ReceiveMode 設定為 ReceiveAndDelete。 您也可以使用 PeekLock 的 ReceiveMode。 這裡,我只想要擷取訊息和處理程序,以及我不需要以確保適當的接收和處理之前,刪除,因為如果遺失的訊息時,它不是個大問題。 如果我必須是保證更可靠的行為,我可能就會做兩件事。 我不訊息、 主題或訂閱,即設定 TTL,而是讓無限期地存留的訊息。 或者,我會讓它非常高的 TTL,讓收件者有足夠的時間來處理,或移例外佇列,以便只有真正無法傳遞的郵件會得到無法投遞的信件佇列中。 此外,我可以使用收件者上的 PeekLock,來讀取和處理資料以及只移除相關的處理程序完成時的訊息。 手動建立這個分散式的交易行為可以快速地造成其他問題,例如污染佇列,但我們稍後會說明該行為和問題設定其他的時間。

一旦我開啟我進入迴圈來檢查郵件的收件者。 API 有直接的 Receive 方法會傳回 BrokeredMessage。 不過,我將使用 TryReceive 方法,會將其傳回 bool,以指示成功 (請參閱圖 5)。 我會將相對較短的逾時傳遞至該方法,應該夠長才能檢查,並且會收到訊息。 如果收到訊息時,我將使用它,並立即檢查另一則訊息。 如果不收到任何訊息時,我會睡眠的位元的執行緒,檢查一次。

檢查郵件的 [圖 5

while (MonitorOn)
{
  BrokeredMessage NewMsg;
  bool recvSuccess = msgReceiver.TryReceive(TimeSpan.FromSeconds(3), out NewMsg);
 
  if (recvSuccess)
  {
    this.lbMessages.Items.Add(NewMsg.MessageId);
    InventoryQueryData RequestObject =
      NewMsg.GetBody<CreateInquiry.InventoryQueryData>();
    ProcessMessage(RequestObject);
  }
  else
  {
    System.Threading.Thread.Sleep(3000);
  }
}

我的要求物件位於 BrokeredMessage,並擷取它,我會把 GetBody <T>,傳遞的物件型別。這裡的含意是物件型別必須符合兩方在匯流排上。若要這樣使用 proxy 型別 ; 的情況下不確定性或透過一般的舊 XML,您可以傳遞物件做為字串,它處理成 XML。

直到下一次...

此時,所有的工作是為了建立訊息,並放到所有想要的節點,並為其擷取訊息的主題。我示範了如何適當地讓我不但廣播訊息,但也篩選訂閱的收件者的功能。下個月我會逐步示範互補使用佇列和完成案例,和您基本的了解 Windows Azure AppFabric 服務匯流排的新功能,來完成相互關聯的傳回往返。我也會有可供您下載的完整程式碼。

Joseph Fultz 是軟體架構設計人員在完成息安全有限公司,使用一部分的 HP.com 通用 IT 群組。 先前,他是使用其最上層企業和定義架構和設計解決方案的ISV 客戶的 microsoft 軟體架構設計人員。

感謝給下列技術專家來檢閱這份文件: Jim Keane