Windows Azure Service Bus (3) 隊列(Queue) 使用VS2013開發Service Bus Queue

  《Windows Azure Platform 系列文章目錄html

    

  在以前的Azure Service Bus中,咱們已經介紹了Service Bus 隊列(Queue)的基本概念。前端

  在本章中,筆者將介紹如何使用Visual Studio 2013,開發一個Service Bus Queue的Demo Project。後端

  

  場景:ide

  1.在前端有一個ASP.NET頁面,客戶從輸入框輸入數據,而且經過按鈕進行提交函數

  2.輸入框輸入的數據,會被後端的WorkerRoleWithSBQueue接受處理,並在後端顯示post

  

  主要步驟有:網站

  1.使用Azure Management Portal,建立Service Busurl

  2.修改Web Role邏輯spa

  3.建立Cloud Project,添加Web Role和Service Bus Worker Role3d

  4.配置WebRole和ServiceBusWorkerRole

  3.DEMO

 

 

  一.筆者已經在以前的文章中,介紹如何建立Service Bus了。不熟悉的讀者,能夠參考Windows Azure Service Bus (2) 隊列(Queue)入門

  

  二.建立Cloud Project

  1.首先咱們以管理員身份,運行VS2013

  2.建立一個新的Cloud Service,命名爲LeiServiceBusQueue,以下圖:

  

  3.增長ASP.NET Web RoleWorker Role with Service Bus Queue。以下圖

  

   

 

 

  二.設置WorkerRoleWithSBQueue1

  1.在WorkerRoleWithSBQueue1項目中,修改WorkerRole.cs代碼,以下:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;

namespace WorkerRoleWithSBQueue1
{
    public class WorkerRole : RoleEntryPoint
    {
        // The name of your queue
        const string QueueName = "ProcessingQueue";// QueueClient is thread-safe. Recommended that you cache 
        // rather than recreating it on every request
        QueueClient Client;
        ManualResetEvent CompletedEvent = new ManualResetEvent(false);

        public override void Run()
        {
            Trace.WriteLine("Starting processing of messages");

            // Initiates the message pump and callback is invoked for each message that is received, calling close on the client will stop the pump.
            Client.OnMessage((receivedMessage) =>
                {
                    try
                    {
                        // Process the message
                        Trace.WriteLine("Processing Service Bus message: " + receivedMessage.SequenceNumber.ToString());

                        string received = receivedMessage.GetBody<string>();
                        Trace.WriteLine("You input is" + received);
                    }
                    catch
                    {
                        // Handle any message processing specific exceptions here
                    }
                });

            CompletedEvent.WaitOne();
        }
    
  
     public override bool OnStart() { // Set the maximum number of concurrent connections ServicePointManager.DefaultConnectionLimit = 12; // Create the queue if it does not exist already string connectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString"); var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString); if (!namespaceManager.QueueExists(QueueName)) { namespaceManager.CreateQueue(QueueName); }// Initialize the connection to Service Bus Queue Client = QueueClient.CreateFromConnectionString(connectionString, QueueName); return base.OnStart(); } public override void OnStop() { // Close the connection to Service Bus Queue Client.Close(); CompletedEvent.Set(); base.OnStop(); } } }

 

  在上面的WokerRole.cs類代碼中,分爲兩個邏輯:

  (1)OnStart函數,表示WorkerRole在啓動的時候,初始化了ProcessingQueue對象

  (2)Run函數,表示在WorkerRole在執行的時候,將ProcessingQueue的內容輸出

 

 

 

  三.設置Web Role

  1.在Web Role的根目錄下,建立一個新的ASPX頁面,重命名爲ServiceBusQueue.aspx

  在ServiceBusQueue.aspx頁面中,

  -  增長一個TextBox控件,重命名爲txbInput

  -  增長一個Button控件,重命名爲BtnSend

  2.在WebRole1項目中,增長NuGet,添加ServiceBus引用。以下圖:

  

  3.在ServiceBusQueue.aspx.cs中,增長以下代碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using Microsoft.WindowsAzure;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;

namespace WebRole1
{
    public partial class ServiceBusQueue : System.Web.UI.Page
    {
        const string QueueName = "ProcessingQueue";

     protected void Page_Load(object sender, EventArgs e) { } protected void BtnSend_Click(object sender, EventArgs e) { string strinput = txbInput.Text.ToString(); Send(strinput); txbInput.Text = string.Empty; } private void Send(string text) { string connectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString"); MessagingFactory factory = MessagingFactory.CreateFromConnectionString(connectionString); // Initialize the connection to Service Bus Queue MessageSender sender = factory.CreateMessageSender(QueueName); BrokeredMessage message1 = new BrokeredMessage(text); sender.Send(message1); } } }

  上面的代碼中,會將用戶從界面的輸入值,插入到ProcessingQueue對象中

 

 

 

  四.配置WebRole和ServiceBusWorkerRole

  咱們修改WebRole的配置文件,以下圖:

  

  在WebRole1的Settings中,點擊Add Setting增長Microsoft.ServiceBus.ConnectionString對象,以下圖:

  

  上圖中,須要將Value值修改成咱們在Azure Management Portal中建立的ServiceBus鏈接字符串,以下圖:

  

 

  修改完畢後,咱們須要修改ServiceBusWorkerRole的配置文件

  

  將Microsoft.ServiceBus.ConnectionString的Value屬性,修改成咱們在Azure Management Portal中建立的ServiceBus鏈接字符串。以下圖:

  

  

 

 

  五.而後咱們用Visual Studio的Azure模擬器運行。

  咱們依次在ServiceBusQueue.aspx中,輸入不一樣的值。以下圖:

                    

  咱們能夠在Azure Compute模擬器中,查看到2次輸入的結果。以下圖:

  

 

  能夠觀察到,首先輸入的值,最早被處理。這也說明了Service Bus Queue 先進先出的特性。

 

  最後咱們還能夠在Management Portal中,查看到由代碼生成的processingqueue對象

  

  

  

 

 

  =====================================分隔符=======================================================

 

  看到最後,若是有讀者以爲,從Azure Compute Emulator查看到aspx頁面的輸入,這也太不智能啦。

  放心,其實咱們能夠將aspx頁面的輸入,返回到另外的ReturnQueue對象中去,並在前端aspx進行顯示:

  (1)ProcessingQueue:插入(Send)數據

  (2)ProcessingQueue:返回(Receive)數據

 

  別問我爲何不能保存到代碼中申明的ProcessingQueue中,筆者試驗過,不能對ProcessingQueue同時執行Send和Receive操做

 

  ServiceBusQueue.aspx.cs代碼以下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using Microsoft.WindowsAzure;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;

namespace WebRole1
{
    public partial class ServiceBusQueue : System.Web.UI.Page
    {
        const string QueueName = "ProcessingQueue";
        const string ReturnQueueName = "ReturnQueue";
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void BtnSend_Click(object sender, EventArgs e)
        {
            string strinput = txbInput.Text.ToString();
            Send(strinput);
            txbInput.Text = string.Empty;
        }

        private void Send(string text)
        {
            string connectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
            MessagingFactory factory = MessagingFactory.CreateFromConnectionString(connectionString);

            // Initialize the connection to Service Bus Queue
            MessageSender sender = factory.CreateMessageSender(QueueName);

            BrokeredMessage message1 = new BrokeredMessage(text);

            sender.Send(message1);

        }

        protected void btnReceiveMessage_Click(object sender, EventArgs e)
        {
           string connectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
           QueueClient Client = QueueClient.CreateFromConnectionString(connectionString, ReturnQueueName);

           var message = Client.Receive(TimeSpan.FromSeconds(3));
           if (message != null)
           {
               var ret = message.GetBody<string>();
               message.Complete();


           }
        }
    }
}

 

  WorkerRole.cs代碼以下:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;

namespace WorkerRoleWithSBQueue1
{
    public class WorkerRole : RoleEntryPoint
    {
        // The name of your queue
        const string QueueName = "ProcessingQueue";
        const string ReturnQueueName = "ReturnQueue";

        // QueueClient is thread-safe. Recommended that you cache 
        // rather than recreating it on every request
        QueueClient Client;
        ManualResetEvent CompletedEvent = new ManualResetEvent(false);

        public override void Run()
        {
            Trace.WriteLine("Starting processing of messages");

            // Initiates the message pump and callback is invoked for each message that is received, calling close on the client will stop the pump.
            Client.OnMessage((receivedMessage) =>
                {
                    try
                    {
                        // Process the message
                        Trace.WriteLine("Processing Service Bus message: " + receivedMessage.SequenceNumber.ToString());

                        string received = receivedMessage.GetBody<string>();
                        Trace.WriteLine("You input is" + received);

                        SendToReturnQueue(ReturnQueueName, received);
                    }
                    catch
                    {
                        // Handle any message processing specific exceptions here
                    }
                });

            CompletedEvent.WaitOne();
        }

        private void SendToReturnQueue(string queueName, string inputString)
        { 
            string connectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
            MessagingFactory factory = MessagingFactory.CreateFromConnectionString(connectionString);

            // Initialize the connection to Service Bus Queue
            MessageSender sender = factory.CreateMessageSender(queueName);

            BrokeredMessage message1 = new BrokeredMessage(inputString);

            sender.Send(message1);

        }

        public override bool OnStart()
        {
            // Set the maximum number of concurrent connections 
            ServicePointManager.DefaultConnectionLimit = 12;

            // Create the queue if it does not exist already
            string connectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
            var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
            if (!namespaceManager.QueueExists(QueueName))
            {
                namespaceManager.CreateQueue(QueueName);
            }
            if (!namespaceManager.QueueExists(ReturnQueueName))
            {
                namespaceManager.CreateQueue(ReturnQueueName);
            }

            // Initialize the connection to Service Bus Queue
            Client = QueueClient.CreateFromConnectionString(connectionString, QueueName);
            return base.OnStart();
        }

        public override void OnStop()
        {
            // Close the connection to Service Bus Queue
            Client.Close();
            CompletedEvent.Set();
            base.OnStop();
        }
    }
}

 

 

 

本博-三石Blog(下文簡稱本博),在本博客文章結尾處右下腳未註明轉載、來源、出處的做品(內容)均爲本博原創,本站對於原創做品內容對其保留版權,請勿隨意轉載,如若真有須要的朋友能夠發Mail聯繫我;轉載本博原創做品(內容)也必須遵循「署名-非商業用途-保持一致」的創做共用協議,請務必以文字連接的形式標明或保留文章原始出處和博客做者(Lei Zhang)的信息,關於本博攝影做品請務必注意保留(www.cnblog.com/threestone)等相關水印版權信息,不然視爲侵犯原創版權行爲;本博謝絕商業網站轉載。版權全部,禁止一切有違中華人民共和國著做權保護法及相關法律和本博(法律)聲明的非法及惡意抄襲。

相關文章
相關標籤/搜索