<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      如何使用網(wǎng)絡(luò)庫實(shí)現(xiàn)應(yīng)用級(jí)消息收發(fā)

      網(wǎng)絡(luò)客戶端ISocketClient和網(wǎng)絡(luò)會(huì)話ISocketSession都繼承了ISocketRemoteISocketRemote表示遠(yuǎn)程通信,核心就是收發(fā)數(shù)據(jù)。
      下面是ISocketRemote接口的主要實(shí)現(xiàn)

      /// <summary>遠(yuǎn)程通信Socket,僅具有收發(fā)功能</summary>
      public interface ISocketRemote : ISocket
      {
          #region 屬性
          /// <summary>遠(yuǎn)程地址</summary>
          NetUri Remote { get; set; }
      
          /// <summary>通信開始時(shí)間</summary>
          DateTime StartTime { get; }
      
          /// <summary>最后一次通信時(shí)間,主要表示會(huì)話活躍時(shí)間,包括收發(fā)</summary>
          DateTime LastTime { get; }
      
          /// <summary>緩沖區(qū)大小</summary>
          Int32 BufferSize { get; set; }
          #endregion
      
          #region 發(fā)送
          /// <summary>發(fā)送數(shù)據(jù)</summary>
          /// <remarks>
          /// 目標(biāo)地址由<seealso cref="Remote"/>決定
          /// </remarks>
          /// <param name="pk">數(shù)據(jù)包</param>
          /// <returns>是否成功</returns>
          Boolean Send(Packet pk);
          #endregion
      
          #region 接收
          /// <summary>接收數(shù)據(jù)。阻塞當(dāng)前線程等待返回</summary>
          /// <returns></returns>
          Packet Receive();
      
          /// <summary>數(shù)據(jù)到達(dá)事件</summary>
          event EventHandler<ReceivedEventArgs> Received;
      
          /// <summary>消息到達(dá)事件</summary>
          event EventHandler<MessageEventArgs> MessageReceived;
          #endregion
      
          #region 數(shù)據(jù)包處理
          /// <summary>粘包處理接口</summary>
          IPacket Packet { get; set; }
      
          /// <summary>異步發(fā)送數(shù)據(jù)并等待響應(yīng)</summary>
          /// <param name="pk"></param>
          /// <returns></returns>
          Task<Packet> SendAsync(Packet pk);
      
          /// <summary>發(fā)送消息并等待響應(yīng)</summary>
          /// <param name="msg"></param>
          /// <returns></returns>
          Task<IMessage> SendAsync(IMessage msg);
          #endregion
      }

       



      一、同步收發(fā)
      一般小型網(wǎng)絡(luò)應(yīng)用,或者個(gè)人學(xué)習(xí)程序,都會(huì)使用同步收發(fā)。
      Send(xxx);
      var buf = Receive();
      這樣向?qū)Ψ?wù)端發(fā)一個(gè)數(shù)據(jù)包,然后同步阻塞等待接收一個(gè)響應(yīng)數(shù)據(jù)。
      同步收發(fā)最大的優(yōu)點(diǎn)就是簡單,容易理解;
      最大的缺點(diǎn)是性能極其底下,并且很大的幾率會(huì)失敗拋出異常,特別是離開本機(jī)或者局域網(wǎng)以后。
      除非網(wǎng)絡(luò)很干凈,客戶端服務(wù)端只進(jìn)行很簡單的通信,否則出錯(cuò)崩潰就是家常便飯!
      并且,這個(gè)階段的工程師,一般認(rèn)為只能客戶端向服務(wù)端發(fā)數(shù)據(jù),而不知道服務(wù)端可以主動(dòng)向客戶端發(fā)數(shù)據(jù)。

      因此,15年經(jīng)驗(yàn)表明,同步收發(fā)根本不適合做產(chǎn)品級(jí)應(yīng)用!

      二、事件驅(qū)動(dòng)
      中大型網(wǎng)絡(luò)應(yīng)用,一般采用事件驅(qū)動(dòng),特別是多并發(fā)服務(wù)端。
      不管是APM還是SAEA,絕大多數(shù)網(wǎng)絡(luò)框架都會(huì)包裝成為事件,或者路由分發(fā)架構(gòu)。
      正如前文接口圖黃色箭頭所示,事件驅(qū)動(dòng)一般用法:
      client.Received += OnReceive;
      client.Send(xxx);
      先建立接收事件,然后發(fā)送數(shù)據(jù),如果對(duì)方有響應(yīng),就會(huì)觸發(fā)OnReceive函數(shù),對(duì)響應(yīng)結(jié)果進(jìn)行處理。

      事件驅(qū)動(dòng)(包括路由分發(fā))是當(dāng)下網(wǎng)絡(luò)框架主流,占比超過70%
      幾乎所有框架都會(huì)在此之外再包裝一層,Send一個(gè)業(yè)務(wù)對(duì)象,內(nèi)部序列化為數(shù)據(jù)后發(fā)出,OnReceive后反序列化得到業(yè)務(wù)對(duì)象,返回給上層。

      事件驅(qū)動(dòng)跟同步業(yè)務(wù)需求是相背而行的。
      如果業(yè)務(wù)需要向服務(wù)端發(fā)送一個(gè)請(qǐng)求,然后等待響應(yīng)結(jié)果,那么事件驅(qū)動(dòng)甚至還不如同步操作好用!
      一般做法是Send里面做堵塞等待,然后OnReceive里面做攔截。
      這也是事件驅(qū)動(dòng)無法進(jìn)一步擴(kuò)大比例的根本原因。

      事件驅(qū)動(dòng)很好很強(qiáng)大,只是特別不適應(yīng)業(yè)務(wù)上的同步操作需求!

      三、異步請(qǐng)求響應(yīng)
      近20年的軟件發(fā)展史,無一例外等同于Web發(fā)展史。
      除了技術(shù)的發(fā)展,Web思維影響了幾乎所有軟件工程師。哪怕初學(xué)者,也很清楚HTTP是請(qǐng)求響應(yīng)模型。在Web開發(fā)里面,所有的業(yè)務(wù)都要基于請(qǐng)求與響應(yīng)。


      于是我們網(wǎng)絡(luò)庫有了第三種選擇。(前文接口圖紫色箭頭)
      Task<Packet> SendAsync(Packet pk);
      Task<IMessage> SendAsync(IMessage msg);
      event EventHandler<MessageEventArgs> MessageReceived;


      異步發(fā)送SendAsync,可以像事件模型那樣在MessageReceived里面處理,也可以 var rs = await SendAsync(pk); 把異步轉(zhuǎn)為同步操作,滿足同步業(yè)務(wù)需求。


      更為重要的是,SendAsync支持單連接通道并行多異步請(qǐng)求
      也就是說,在一個(gè)網(wǎng)絡(luò)連接上,第一個(gè)請(qǐng)求的響應(yīng)還沒有收到之前,業(yè)務(wù)邏輯可以連續(xù)發(fā)出更多的請(qǐng)求,不管這些請(qǐng)求的響應(yīng)包先后順序以后,網(wǎng)絡(luò)庫都能夠準(zhǔn)確配對(duì),讓await SendAsync得到正確的結(jié)果。
      這就解決了一個(gè)極為常見的問題,一個(gè)業(yè)務(wù)應(yīng)用里面,可能多個(gè)線程需要向服務(wù)端請(qǐng)求數(shù)據(jù),而傳統(tǒng)做法只能是加鎖,在第一個(gè)請(qǐng)求響應(yīng)完成之前,阻塞其它請(qǐng)求。


      實(shí)際上,HTTP 1.0/1.1正是傳統(tǒng)做法,前一個(gè)請(qǐng)求完成之前,不能發(fā)起新的請(qǐng)求,導(dǎo)致瀏覽器不得不建立多個(gè)Tcp連接。


      因此,異步請(qǐng)求響應(yīng)的架構(gòu)設(shè)計(jì),讓請(qǐng)求響應(yīng)準(zhǔn)確配對(duì),支持并行請(qǐng)求,并且解決一切粘包問題!


      應(yīng)用級(jí)消息收發(fā)偽代碼:

      var str = "{action:Open,args:{index:3},remark:打開3號(hào)燈}";
      var client = new NetUri("tcp://127.0.0.1:1234").CreateRemote();
      client.Packet = new DefaultPacket();
      var rs = await client.SendAsync(str.GetBytes());
      // rs = "{result:true,data:3號(hào)燈已打開}"

      上面的DefaultPacket正是 新生命團(tuán)隊(duì)標(biāo)準(zhǔn)網(wǎng)絡(luò)封包協(xié)議
      請(qǐng)求響應(yīng)包的頭部,都會(huì)增加4字節(jié),Json字符串作為負(fù)載數(shù)據(jù)。
      正是增加的這4字節(jié),確保了請(qǐng)求響應(yīng)的準(zhǔn)確配對(duì)(序列號(hào)匹配),解決了粘包問題(頭部長度)


      即使沒有默認(rèn)封包DefualtPacket,上面代碼也是可以工作的,只是這樣就失去了準(zhǔn)確配對(duì)和粘包拆分,要求業(yè)務(wù)層不能頻繁收發(fā)。


      End.

      posted @ 2017-08-30 22:51  大石頭  閱讀(699)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 国产国产久热这里只有精品| mm1313亚洲国产精品| 最新中文字幕国产精品| 超碰人人超碰人人| 亚洲人成网线在线播放VA| 人妻少妇精品中文字幕| 久久精品国产亚洲综合av| 精品一区二区三区在线观看l| 亚洲日韩久热中文字幕| 日韩卡一卡2卡3卡4卡| 成人福利一区二区视频在线| 99riav精品免费视频观看| 国产精品成人一区二区不卡| 亚洲韩欧美第25集完整版| 亚洲伊人久久大香线蕉| 日韩一区在线中文字幕| 国产网红主播精品一区| 久久国产精品伊人青青草| 大香j蕉75久久精品免费8| 久久久久国产精品熟女影院| 日韩一区二区三区水蜜桃| 人妻另类 专区 欧美 制服| 五月丁香激激情亚洲综合| 日本黄色一区二区三区四区| 少妇人妻无码专区在线视频| 亚洲av免费成人精品区| 日本熟妇色xxxxx| 国产精品国产三级在线专区| 国产精品国产精品一区精品| 亚洲欧美日韩精品久久| 国产在线播放专区av| 欧美成人aaa片一区国产精品| 日本视频精品一区二区| 日韩亚av无码一区二区三区 | 亚洲第一综合天堂另类专| 影视先锋av资源噜噜| 一区二区三区午夜福利院| 亚洲人成网站18禁止无码| 岳池县| 全免费A级毛片免费看无码| 欧美黑人XXXX性高清版|