1. 程式人生 > >長輪詢 VS 短輪詢

長輪詢 VS 短輪詢

響應 tcp 朋友 輪詢 決定 多次 有一個 存在 新浪

創建基礎Web的實時系統時,通常會使用的到HTTP,但HTTP天生不是為實時,雙向溝通設計的。我們如何解決這個問題呢?

我們先來看一下HTTP協議:

http 協議介紹:

http 協議是請求/響應範式的, 每一個 http 響應都是由一個對應的 http 請求產生的; http 協議是無狀態的, 多個 http 請求之間是沒有關系的.

http 長連接:

目前 http 協議普遍使用的是 1.1 版本, 之前有個 1.0 版本, 兩者之間的一個區別是 1.1 支持 http 長連接, 或者叫持久連接.1.0 不支持 http 長連接, 每次一個 http 請求響應後都關閉 tcp 連接, 下個 http 請求會重新建立 tcp 連接.

所謂 http 長連接, 就是多個 http 請求共用一個 tcp 連接; 這樣可以減少多次臨近 http 請求導致 tcp 建立關閉所產生的時間消耗. http 1.1 中在請求頭和相應頭中用 connection字段標識是否是 http 長連接, connection: keep-alive, 表明是 http 長連接; connection:closed, 表明服務器關閉 tcp 連接

與 connection 對應的一個字段是 keep-live, http 響應頭中出現, 他的格式是 timeout=30, max=5, timeout 是兩次 http 請求保持的時間(s), , max 是這個 tcp 連接最多為幾個 http 請求重用

http 長輪詢:

http 長輪詢是服務器收到請求後如果有數據, 立刻響應請求; 如果沒有數據就會 hold 一段時間, 這段時間內如果有數據立刻響應請求; 如果時間到了還沒有數據, 則響應 http 請求;瀏覽器受到 http 響應後立在發送一個同樣 http 請求查詢是否有數據;

http 長輪詢的局限:

  1. 瀏覽器端對統一服務器同時 http 連接有最大限制, 最好同一用戶只存在一個長輪詢;
  2. 服務器端沒有數據 hold 住連接時會造成浪費, 容易產生服務器瓶頸;

http 短輪詢:

http端輪詢是服務器收到請求不管是否有數據都直接響應 http 請求; 瀏覽器受到 http 響應隔一段時間在發送同樣的 http 請求查詢是否有數據;

http 短輪詢的局限是實時性低;

兩者相同點:
可以看出 http 長輪詢和 http 短輪詢的都會 hold 一段時間;

兩者不同點
間隔發生在服務端還是瀏覽器端: http 長輪詢在服務端會 hold 一段時間, http 短輪詢在瀏覽器端 “hold” 一段時間;

應用:

長輪詢一般用在 web im, im 實時性要求高, http 長輪詢的控制權一直在服務器端, 而數據是在服務器端的, 因此實時性高;
像新浪微薄的im, 朋友網的 im 以及 webQQ 都是用 http 長輪詢實現的;
NodeJS 的異步機制貌似可以很好的處理 http 長輪詢導致的服務器瓶頸問題, 這個有待研究.

http 短輪詢一般用在實時性要求不高的地方, 比如新浪微薄的未讀條數查詢就是瀏覽器端每隔一段時間查詢的.

其他:

關於 http 長連接一個誤解就是服務器主動推送數據, 這個在 http 協議下是無法實現的, 因為 http 請求/響應範式決定的, http 中服務器返回數據必須要有一個瀏覽器端的請求對應, 服務器無法主動推送給瀏覽器數據.
不管 http 長輪詢還是 http 短輪詢 保證同一個用戶在多 tab 下只存在一個定時查詢是有好處的, 這可以通過在瀏覽器端緩存數據解決, 在 http 響應後在瀏覽器端緩存數據, 並設置一個有效期, 然後在每次發送 http 請求時檢查是否有有效數據, 沒有則發送請求獲取

長輪詢 VS 短輪詢