如何構(gòu)建應(yīng)用程序引擎以及使用 Windows Azure Storage 實(shí)現(xiàn)異步消息傳送
圖 7 以 toast 形式消息顯示的通知本文引用地址:http://www.ex-cimer.com/article/149634.htm
$(document).ready(function() {
setInterval(function() {
$.ajax({
contentType: application/json; charset=utf-8,
dataType: json,
url: /SystemMessage/GetMessages,
success: function(data) {
for (msg in data) {
$.gritter.add({
title: data[msg].title,
text: data[msg].text,
sticky: false
});
}
}
})
}, 15000)
});
提交和處理購(gòu)物車(chē)
在我們的示例應(yīng)用程序中,我們希望使用隊(duì)列存儲(chǔ)執(zhí)行的另一個(gè)關(guān)鍵方案是提交購(gòu)物車(chē)。Hollywood Hackers 有一個(gè)第三方履行系統(tǒng)(Hollywood Hackers 無(wú)法在其空間有限的倉(cāng)庫(kù)中保留所有小工具),所以引擎需要對(duì)購(gòu)物車(chē)進(jìn)行一些處理。一旦引擎完成其處理,它會(huì)向用戶(hù)通知隊(duì)列提交一個(gè)消息,告知用戶(hù)已經(jīng)對(duì)購(gòu)物車(chē)進(jìn)行了處理(或者出現(xiàn)了問(wèn)題)。如果處理購(gòu)物車(chē)時(shí)用戶(hù)處于在線(xiàn)狀態(tài),該用戶(hù)將收到系統(tǒng)彈出的一個(gè) toast 消息。如果用戶(hù)不在線(xiàn),則會(huì)在其下次登錄到該站點(diǎn)時(shí)收到該彈出消息,如圖 8 所示。
圖 8 示例用戶(hù)通知
查看原圖(大圖)
我們首先需要的是一些包裝類(lèi),使我們可以與購(gòu)物車(chē)隊(duì)列交互。這些包裝非常簡(jiǎn)單,如果要查看它們的源代碼,可以在 CodePlex 站點(diǎn)上查看。
與標(biāo)準(zhǔn) CRUD(創(chuàng)建、讀取、更新、刪除)存儲(chǔ)庫(kù)不同的是,隊(duì)列中的讀取操作不是單純的讀取操作。請(qǐng)記住,只要獲取隊(duì)列中的消息,必須在有限的時(shí)間內(nèi)處理該消息,操作失敗或刪除消息都會(huì)顯示處理完成。這種模式不能順利地轉(zhuǎn)換到存儲(chǔ)庫(kù)模式,所以我們已經(jīng)不再借助包裝類(lèi)執(zhí)行此操作。
現(xiàn)在,我們已經(jīng)擁有了要與購(gòu)物車(chē)隊(duì)列交互的代碼,我們可以將一些代碼放在購(gòu)物車(chē)控制器中,以便將購(gòu)物車(chē)內(nèi)容提交到隊(duì)列中(請(qǐng)參見(jiàn)圖 9)。
圖 9 向隊(duì)列提交購(gòu)物車(chē)
public ActionResult Submit()
{
ShoppingCartMessage cart = new ShoppingCartMessage();
cart.UserName = User.Identity.Name;
cart.Discounts = 12.50f;
cart.CartID = Guid.NewGuid().ToString();
ListShoppingCartItem> items = new ListShoppingCartItem>();
items.Add(new ShoppingCartItem()
{ Quantity = 12, SKU = 10000101010,
UnitPrice = 15.75f });
items.Add(new ShoppingCartItem()
{ Quantity = 27, SKU = 12390123j213,
UnitPrice = 99.92f });
cart.CartItems = items.ToArray();
cartQueue.AddMessage(cart);
return View();
}
在實(shí)際情況下,您可能會(huì)從進(jìn)程外狀態(tài)(例如會(huì)話(huà)存儲(chǔ)、緩存或窗體發(fā)布)獲得購(gòu)物車(chē)。為了簡(jiǎn)化本文代碼,我們僅僅構(gòu)建了購(gòu)物車(chē)的內(nèi)容。
最后,購(gòu)物車(chē)內(nèi)容已處于隊(duì)列中,我們可以修改工作者角色,以便它可以定期檢查隊(duì)列中掛起的購(gòu)物車(chē)。它每次會(huì)從隊(duì)列中選擇一個(gè)購(gòu)物車(chē),用整整一分鐘對(duì)該購(gòu)物車(chē)進(jìn)行處理,然后向用戶(hù)通知隊(duì)列提交一個(gè)消息,告知用戶(hù)已經(jīng)對(duì)該購(gòu)物車(chē)進(jìn)行了處理(請(qǐng)參見(jiàn)圖 10)。
圖 10 檢查隊(duì)列中掛起的購(gòu)物車(chē)
private void ProcessShoppingCarts()
{
CloudQueueMessage cqm = cartQueue.GetMessage();
while (cqm != null)
{
ShoppingCartMessage cart =
QueueMessageBase.FromMessageShoppingCartMessage>(cqm);
toastRepository.AddNotification(new UserTextNotification()
{
MessageText = String.Format
(Your shopping cart containing {0} items has been processed.,
cart.CartItems.Length),
MessageDate = DateTime.Now,
TargetUserName = cart.UserName
});
cartQueue.DeleteMessage(cqm);
cqm = cartQueue.GetMessage();
}
}
經(jīng)過(guò)對(duì)用戶(hù)通知表中的隊(duì)列消息的存取操作,位于主頁(yè)面中的 jQuery Gritter 代碼然后會(huì)在下一個(gè) 15 秒的輪詢(xún)周期中檢測(cè)是否存在新消息,然后向用戶(hù)顯示購(gòu)物車(chē) toast 通知。
總結(jié)和后續(xù)操作
本文的目的是使開(kāi)發(fā)人員可以?huà)侀_(kāi)其有形的數(shù)據(jù)中心這條“安全毛毯”,認(rèn)識(shí)到他們可以使用 Windows Azure 執(zhí)行很多操作,而不僅僅是創(chuàng)建簡(jiǎn)單的“Hello World”網(wǎng)站。借助 Windows Azure Queues 和 Windows Azure 表存儲(chǔ)的強(qiáng)大功能,以及利用這些強(qiáng)大功能在應(yīng)用程序和其工作者角色之間進(jìn)行異步消息傳送,您可以真正使用 Windows Azure 增強(qiáng)應(yīng)用程序的引擎了。
為使文章簡(jiǎn)明易懂,我們將很多代碼都保留為原樣,沒(méi)有進(jìn)行重構(gòu)。作為熟悉新 Windows Azure Muscle 的練習(xí),請(qǐng)嘗試重構(gòu)本文中的一些代碼,以加深對(duì)隊(duì)列的熟練使用,甚至創(chuàng)建一個(gè)獨(dú)立的程序集,其中包含為任何 ASP.NET MVC 網(wǎng)站進(jìn)行異步消息傳送和通知所需的所有代碼。
主要是親自動(dòng)手實(shí)踐,創(chuàng)建一些站點(diǎn)并看看您都可以執(zhí)行哪些操作。本文中的代碼位于 Hollywood Hackers 的 CodePlex 站點(diǎn)中。
評(píng)論