循序漸進做項目系列(2):最簡單的C/S程序——消息異步調用與消息同步調用



上篇博客 循序漸進做項目系列(1):最簡單的C/S程序——讓服務器來做加法 實現了一個最簡單的
C/S程序,即讓服務器來做加法。當時為了通俗易懂采用了消息異步調用的方式。今天我們要采用消息同步調用的方式來實現,並且對比一下兩種方式的優劣。通過這個實例也能讓對於“同步調用異步調用”不甚了了的朋友們對於這一對概念有一個初步直觀的認識。

  究竟什么是消息同步調用什么是消息異步調用呢?

一·消息異步調用 

  對於這個問題我們先不急於從原理上回答,先來看下上一次客戶端向服務端發送消息的代碼。
        private void button1_Click(object sender, EventArgs e)
        {
            int leftNum = int.Parse(this.textBox_leftNum.Text);
            int rightNum = int.Parse(this.textBox_rightNum.Text);
            //將數據轉碼以備發送給服務端
            byte[] leftNumCode = BitConverter.GetBytes(leftNum);
            byte[] rightNumCode = BitConverter.GetBytes(rightNum);
            byte[] NumbersCode = new byte[8];//用來合並待發送的消息(一個整型占4個字節)
            for (int i = 0; i < 4; i++)
            {
                NumbersCode[i] = leftNumCode[i];//第一個數的編碼裝進前四位
            }
            for (int j = 0; j < 4; j++)
            {
                NumbersCode[j + 4] = rightNumCode[j];//第二個數的編碼裝進后四位
            }
           //發送給服務器,100代表做加法這件事
            Program.clientEngine.CustomizeOutter.Send(100, NumbersCode);
        }

      關鍵是客戶端發消息的那句代碼,發完消息后客戶端就撒手不管了,究竟服務端有沒有收到呢?會不會發出去的消息就是“肉包子打狗”呢?客戶端不得而知。反正皮球踢給了服務端,好吧服務端接了,然后服務端是這樣做的:

 //該方法用來處理客戶端通過clientEngine.CustomizeOutter.Send()方法發送過來的消息
        public void HandleInformation(string sourceUserID, int informationType, byte[] info)
        {
            if (informationType == 100)
            {
                int leftNum = BitConverter.ToInt32(info, 0);//將字節數組前四位還原成leftNum
                int rigthNum = BitConverter.ToInt32(info, 4);//將字節數組后四位還原成rigthNum
                int result = leftNum + rigthNum;
                byte[] resultCode = BitConverter.GetBytes(result);//將計算結果轉碼
                this.serverEngine.CustomizeController.Send(sourceUserID, 100, resultCode);//發送給對應的客戶端
            }          
        }

       服務端處理一番后再度發消息給客戶端,又一個皮球踢了出去。客戶端接球:

 //該方法來處理服務端Send()方法發送過來的消息
        public void HandleInformation(string sourceUserID, int informationType, byte[] info)
        {
            if (informationType == 100)
            {
                MessageBox.Show("結果為:" + BitConverter.ToInt32(info, 0));
            }
        }

      綜上就是消息異步調用,就是發送者只發消息,僅此而已,發完消息該干嘛干嘛,接受者接收消息后再向發送者發消息時,自身角色同時也轉換為發送者,按發送者的風格行事。但是從上述過程中可以看出,采用消息異步調用會使得通信過程較為復雜,需要反復“收發”消息。

二·消息同步調用

      我們再來看看消息同步調用是怎么做的:

        private void button1_Click(object sender, EventArgs e)
        {
            int leftNum = int.Parse(this.textBox_leftNum.Text);
            int rightNum = int.Parse(this.textBox_rightNum.Text);
            //將數據轉碼以備發送給服務端
            byte[] leftNumCode = BitConverter.GetBytes(leftNum);
            byte[] rightNumCode = BitConverter.GetBytes(rightNum);
            byte[] NumbersCode = new byte[8];//用來合並待發送的消息,一個整型占4個字節
            for (int i = 0; i < 4; i++)
            {
                NumbersCode[i] = leftNumCode[i];//第一個數的編碼裝進前四位
            }
            for (int j = 0; j < 4; j++)
            {
                NumbersCode[j + 4] = rightNumCode[j];//第二個數的編碼裝進后四位
            }
            //發送給服務器請求獲取結果
            byte[] resultCode = Program.clientEngine.CustomizeOutter.Query(100, NumbersCode); int result = BitConverter.ToInt32(resultCode, 0);//解析
            MessageBox.Show("結果為:" + result);
        }

      重點是發消息語句,與前面的“異步調用”的區別就在於請求返回結果,然而處理過程並不是在客戶端的主機上完成的,而是在服務端:

   //該方法用來處理客戶端發送過來的請求,即clientEngine.CustomizeOutter.Query()方法發送過來的消息
        public byte[] HandleQuery(string sourceUserID, int informationType, byte[] info)
        {
            if (informationType == 100)
            {
                int leftNum = BitConverter.ToInt32(info, 0);//將字節數組前四位還原成leftNum
                int rigthNum = BitConverter.ToInt32(info, 4);//將字節數組后四位還原成rigthNum
                int result = leftNum + rigthNum;
                byte[] resultCode = BitConverter.GetBytes(result);//將計算結果轉碼
                return resultCode;
            }
            return null;
        }
   

      表面上類似於調用本地方法,但實質上是一個分布式處理過程。在服務端處理信息的過程中,客戶端一直處於等待狀態,直到服務端處理完畢返回結果。假使該語句下還有代碼塊,則在等待過程中不能夠執行。這就是消息同步調用。

三·總結

      消息同步調用與消息異步調用的概念脫胎於同步調用與異步調用的概念,相當於是對於原概念的拓展。同步調用與異步調用是對於方法的調用而言,所謂同步調用,就是在調用一個方法時,在沒有得到結果之前,主調線程處在等待狀態;所謂異步調用即,一個方法被調用后,主調線程不用等待結果返回。我們這里所談的消息同步調用與消息異步調用是針對於“發送/回復”這種通信的邏輯模型而言,能夠立即獲得回復的發送稱為消息同步調用,反之稱為消息異步調用。

      類似於方法同步調用,消息同步調用也會阻塞當前調用線程,但是由於其模型簡單直觀,而且將“發送“與”回復”嚴格匹配,在其適用的場合較消息異步調用模型具有優越性。

      毫無疑問,在通信框架中,原始的模型就是異步調用模型,而ESFramework也增加了同步調用的機制,使得編程模型更加豐富。

      至於消息同步調用與消息異步調用在實際的項目中如何運用來實現更復雜的需求,完成更強勁的功能,我會在該系列以后的博文中繼續探討,支持的朋友請頂一頂,給與我堅持不懈的力量!

四.源碼下載

  讓服務器做加法2--同步調用模型

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM