Cloud Service中包含兩類角色:WebRole和WorkerRole。這些Roles們可以理解為不同的虛擬機器,唯一的區別即為:WebRole用來寄宿Web網站,可以把它理解為一台安裝了IIS的虛擬機器。WorkerRole能用來寄宿後台服務,例如:windows 服務神馬的。初步看來,我們是可以用Cloud Service快速的打造N層架的商業程式,什麼3層,4層什麼的。 本文將會介紹一個小例子,如何使用Cloud Service搭建一個三層架構的Web網站。這網站的功能十分的簡單:1)在Web頁面上顯示儲存在Azure Sql Server中的記錄,2)通過 Service Bus Queue 向 WorkerRole處理常式發生Mesage, 3)WorkerRole接受到Queue中的Message後並將訊息中儲存的記錄插入到Azure Sql Server中。工程代碼結構WebRole和WorkerRole工程結構程式功能WebRole實現代碼Aspx
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server"> <h1>Customer Information Management</h1> <p> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:gbsql01ConnectionString %>" SelectCommand="select * from customers"></asp:SqlDataSource> <asp:ListView ID="ListView1" runat="server" DataKeyNames="Id" DataSourceID="SqlDataSource1" InsertItemPosition="LastItem" OnItemInserting="ListView1_ItemInserting" OnItemUpdating="ListView1_ItemUpdating"> <AlternatingItemTemplate> <tr style="background-color: #FAFAD2;color: #284775;"> <td> <asp:Label ID="IdLabel" runat="server" Text='<%# Eval("Id") %>' /> </td> <td> <asp:Label ID="NameLabel" runat="server" Text='<%# Eval("Name") %>' /> </td> <td> <asp:Label ID="EmailLabel" runat="server" Text='<%# Eval("Email") %>' /> </td> </tr> </AlternatingItemTemplate> <EditItemTemplate> <tr style="background-color: #FFCC66;color: #000080;"> <td> <asp:Button ID="UpdateButton" runat="server" CommandName="Update" Text="Update" /> <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="Cancel" /> </td> <td> <asp:Label ID="IdLabel1" runat="server" Text='<%# Eval("Id") %>' /> </td> <td> <asp:TextBox ID="NameTextBox" runat="server" Text='<%# Bind("Name") %>' /> </td> <td> <asp:TextBox ID="EmailTextBox" runat="server" Text='<%# Bind("Email") %>' /> </td> </tr> </EditItemTemplate> <EmptyDataTemplate> <table runat="server" style="background-color: #FFFFFF;border-collapse: collapse;border-color: #999999;border-style:none;border-width:1px;"> <tr> <td>No data was returned.</td> </tr> </table> </EmptyDataTemplate> <InsertItemTemplate> <tr style=""> <td> <asp:Button ID="InsertButton" runat="server" CommandName="Insert" Text="Insert" /> <asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="Clear" /> </td> <td> <asp:TextBox ID="IdTextBox" runat="server" Text='<%# Bind("Id") %>' /> </td> <td> <asp:TextBox ID="NameTextBox" runat="server" Text='<%# Bind("Name") %>' /> </td> <td> <asp:TextBox ID="EmailTextBox" runat="server" Text='<%# Bind("Email") %>' /> </td> </tr> </InsertItemTemplate> <ItemTemplate> <tr style="background-color: #FFFBD6;color: #333333;"> <td> <asp:Label ID="IdLabel" runat="server" Text='<%# Eval("Id") %>' /> </td> <td> <asp:Label ID="NameLabel" runat="server" Text='<%# Eval("Name") %>' /> </td> <td> <asp:Label ID="EmailLabel" runat="server" Text='<%# Eval("Email") %>' /> </td> </tr> </ItemTemplate> <LayoutTemplate> <table runat="server"> <tr runat="server"> <td runat="server"> <table id="itemPlaceholderContainer" runat="server" border="1" style="background-color: #FFFFFF;border-collapse: collapse;border-color: #999999;border-style:none;border-width:1px;font-family: Verdana, Arial, Helvetica, sans-serif;"> <tr runat="server" style="background-color: #FFFBD6;color: #333333;"> <th runat="server">Id</th> <th runat="server">Name</th> <th runat="server">Email</th> </tr> <tr id="itemPlaceholder" runat="server"> </tr> </table> </td> </tr> <tr runat="server"> <td runat="server" style="text-align: center;background-color: #FFCC66;font-family: Verdana, Arial, Helvetica, sans-serif;color: #333333;"></td> </tr> </table> </LayoutTemplate> <SelectedItemTemplate> <tr style="background-color: #FFCC66;font-weight: bold;color: #000080;"> <td> <asp:Label ID="IdLabel" runat="server" Text='<%# Eval("Id") %>' /> </td> <td> <asp:Label ID="NameLabel" runat="server" Text='<%# Eval("Name") %>' /> </td> <td> <asp:Label ID="EmailLabel" runat="server" Text='<%# Eval("Email") %>' /> </td> </tr> </SelectedItemTemplate> </asp:ListView> </p></asp:Content>
private void SendAddCustomerMsg(Hashtable item) { NamespaceManager nm = NamespaceManager.Create(); QueueClient client = QueueClient.Create("jeffqueue",ReceiveMode.ReceiveAndDelete); BrokeredMessage msg = new BrokeredMessage(item); try { client.Send(msg); } catch { throw; } finally { client.Close(); } }
protected void ListView1_ItemInserting(object sender, ListViewInsertEventArgs e) { Hashtable item = new Hashtable(); item.Add("Id", e.Values["Id"]); item.Add("Name", e.Values["Name"]); item.Add("Email", e.Values["Email"]); SendAddCustomerMsg(item); e.Cancel = true; }
WorkerRole實現代碼
using System;using System.Collections;using System.Collections.Generic;using System.Diagnostics;using System.Data;using System.Data.Sql;using System.Data.SqlClient;using System.Linq;using System.Net;using System.Threading;using Microsoft.WindowsAzure;using Microsoft.WindowsAzure.Diagnostics;using Microsoft.WindowsAzure.ServiceRuntime;using Microsoft.WindowsAzure.Storage;using Microsoft.ServiceBus;using Microsoft.ServiceBus.Messaging;namespace gbworkerrole1{ public class WorkerRole : RoleEntryPoint { NamespaceManager nm; QueueClient client; public override void Run() { // This is a sample worker implementation. Replace with your logic. Trace.TraceInformation("gbworkerrole1 entry point called", "Information"); while (true) { BrokeredMessage msg = client.Receive(TimeSpan.FromSeconds(5)); if (msg != null) { SqlConnection conn = new SqlConnection("Data Source=gaalnvmd7w.database.windows.net;Initial Catalog=gbsql01;Persist Security Info=True;User ID=account;Password=pwd"); SqlCommand cmd = new SqlCommand("insert into customers values(@id,@name,@email)", conn); Hashtable item = msg.GetBody<Hashtable>(); cmd.Parameters.AddWithValue("@Id", item["Id"]); cmd.Parameters.AddWithValue("@Name", item["Name"]); cmd.Parameters.AddWithValue("@Email", item["Email"]); try { conn.Open(); cmd.ExecuteNonQuery(); } catch { } finally { if (conn.State == ConnectionState.Open) { conn.Close(); } } } } } public override bool OnStart() { // Set the maximum number of concurrent connections ServicePointManager.DefaultConnectionLimit = 12; // For information on handling configuration changes // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357. nm = NamespaceManager.Create(); client = QueueClient.Create("jeffqueue", ReceiveMode.ReceiveAndDelete); return base.OnStart(); } public override void OnStop() { client.Close(); base.OnStop(); } }}