1. 程式人生 > >關於輪詢與長輪詢的分享

關於輪詢與長輪詢的分享

一、輪詢

  1、輪詢(Polling)是一種CPU決策如何提供周邊裝置服務的方式,又稱“程控輸入輸出”(Programmed I/O)。輪詢法的概念是:由CPU定時發出詢問,依序詢問每一個周邊裝置是否需要其服務,有即給予服務,服務結束後再問下一個周邊,接著不斷周而復始。

  2、輪詢是基站為終端分配頻寬的一種處理流程,這種分配可以是針對單個終端或是一組終端的。為單個終端和一組終端連線分配頻寬,實際上是定義頻寬請求競爭機制,這種分配不是使用一個單獨的訊息,而是上行鏈路對映訊息中包含的一系列分配機制。

  3、輪詢是基於終端的,頻寬的請求總是基於CID,而分配則是基於終端。

  4、簡單來說,輪詢就是客戶端定時去請求服務端,  是客戶端主動請求來促使資料更新;

  短輪詢的基本思路:

    就是瀏覽器每隔一段時間向瀏覽器傳送http請求,伺服器端在收到請求後,不論是否有資料更新,都直接進行響應。這種方式實現的即時通訊,本質上還是瀏覽器傳送請求,伺服器接受請求的一個過程,通過讓客戶端不斷的進行請求,使得客戶端能夠模擬實時地收到伺服器端的資料的變化。

  優點:

    比較簡單,易於理解,實現起來也沒有什麼技術難點。缺點是顯而易見的,這種方式由於需要不斷的建立http連線,嚴重浪費了伺服器端和客戶端的資源。尤其是在客戶端,距離來說,如果有數量級想對比較大的人同時位於基於短輪詢的應用中,那麼每一個使用者的客戶端都會瘋狂的向伺服器端傳送http請求,而且不會間斷。人數越多,伺服器端壓力越大,這是很不合理的。

    因此短輪詢不適用於那些同時線上使用者數量比較大,並且很注重效能的Web應用。

  接下來通過一個簡單的小例子給大家演示一下:

客戶端:

<body>
    <label id="lbPolling"></label>
    <script>
        $(function () {
            //輪詢,每隔1秒就請求一次
            setInterval(function () {
                debugger;
                $.get("../Home/lbPolling", function (data) {
                    debugger;
                    $("#lbPolling").html("輪詢:" + new Date().toLocaleString());
                });
            }, 1000);
        })
    </script>
</body>

服務端:

        /// <summary>
        /// 輪詢,只要客戶端請求就返回資料
        /// </summary>
        /// <returns></returns>
        public ActionResult lbPolling()
        {
            return Content(DateTime.Now.ToString());
        }    

二、長輪詢  

下面這一段引用:https://www.cnblogs.com/Leo_wl/p/3222076.html,講的蠻好的,這裡引用學習一下。

HTTP協議本身有兩個“漏洞”,也是現在網路通訊中無法避免的。

  1、請求(Request)和答覆(Response)之間無法確認其連線狀況,可就無法確定其所用的時限了。判斷客戶端與服務端是否相連的一個標準就是客戶端的請求是否能收到服務端的答覆,如果收得到,就說明連線上了,即時收到的是服務端錯誤的通知(比如404 not found)。

  2、在獲取到答覆(Response)前,都無法知道所需要的資料內容是怎麼樣的(如果有還跟人家要啥)。

原理:

長輪詢就是利用了這兩個“漏洞”:服務端收到請求(Request)後,將該請求Hold住不馬上答覆,而是一直等,等到服務端有資訊需要傳送給客戶端的時候,通過將剛才Hold住的那條請求(Request)的答覆(Response)發回給客戶端,讓客戶端作出反應。而返回的內容,那就隨便服務端了。

然後,客戶端收到答覆(Response)後,馬上再重新發送一次請求(Request)給服務端,讓服務端再Hold住這條連線。周而復始,就實現了從服務端向客戶端傳送訊息的實時通訊,客戶端向服務端傳送訊息則依舊利用傳統的Post和Get進行。

受Web通訊現實情況限制,如果服務端長時間沒有訊息需要推送到客戶端的時候,也不能一直Hold住那條連結,因為很有可能被判定為閘道器超時等超時情況。所以即使沒有訊息,每間隔一段時間,服務端也要返回一個答覆(Response),讓客戶端重新請求一個連結。

見過一些人喜歡把每次輪詢的斷開到下次輪詢開始客戶端的接收->再請求的行為稱之為一次“心跳(Beat)”,也挺貼切的。

要實現真正的實時通訊,長輪詢的實現並不那麼簡單,因為每次“心跳”時會產生一個小間隙,這個間隙的時候服務端已經將上一個答覆(Response)返回,但還沒有接收到客戶端的下一次請求(Request)。那麼這時候,服務端如果有最新訊息,就無法推送給客戶端了,所以需要將這些訊息快取起來,等到下一次機會到來的時候再XXOO。

理解:

  1、傳統的輪詢是前端ajax輪詢,每隔一段時間發一個請求,伺服器響應後馬上關掉連線,但是這種方式明顯有很大的開銷,所以才有了長輪詢,就是響應時間變長了,瀏覽器(客戶端)傳送一個請求,伺服器hold住連線(就是迴圈加睡覺,可以到網上找找簡單的實現程式碼),等有訊息的時候才返回,當然瀏覽器的這個連線在這個過程中可以阻塞也可以非同步非阻塞,ajax是非同步的,等等,你說了這麼多我還是不知道為什麼長輪詢可以當push技術用,和傳統的有什麼區別,這裡說一下,長輪詢技術要求伺服器一旦傳送了響應,客戶端必須馬上再發一個請求,這就變成了伺服器是主動方,所以才說是一種偽push技術。
  2、跟輪詢一樣也是客戶端請求服務端,但是服務端並不是即時返回,而是當有內容更新的時候才返回內容給客戶端,從流程上講,可以理解為伺服器向客戶端推送內容;

  接下來通過一個簡單的小例子給大家演示一下:

客戶端:

<body>
    <label id="lbLongPolling"></label>
    <script>
        $(function () {
           //長輪詢,請求服務端,等到響應了,再次請求
            var SendLongPolling = function () {
                $.get("../Home/LongPolling", function (data) {
                    debugger;
                    $("#lbLongPolling").html("長輪詢:" + data);
                    SendLongPolling();
                });
            };
            SendLongPolling();
        })
    </script>
</body>

服務端:

         /// <summary>
        /// 長輪詢,模擬掛起的操作,伺服器每秒會有更新,然後返回給客戶端實時資料
        /// </summary>
        /// <returns></returns>
        public ActionResult LongPolling()
        {
            while (true)
            {
                Thread.Sleep(1000);
                return Content(DateTime.Now.ToString());
            }
        }    

輪詢和長輪詢的區別:

輪詢:

1:大量耗費伺服器記憶體和寬頻資源,因為不停的請求伺服器,很多時候 並沒有新的資料更新,因此絕大部分請求都是無效請求

2:資料不一定是實時更新,要看設定的請求間隔,基本會有延遲。

長輪詢:

1:解決了輪詢的兩個大問題,資料實時更新;

2:唯一的缺點是伺服器在掛起的時候比較耗記憶體;

文章摘錄:https://www.cnblogs.com/wolfworker/p/7346625.html

 

ok,今天的分享就到這裡,如有不妥歡迎指正,感謝!