1. 程式人生 > >http長連線、長輪詢的理解

http長連線、長輪詢的理解

昨天翻了翻《HTTP權威指南》,看到HTTP連線管理這節,書中講到了HTTP事務,突然發現事務一詞在好多場合都用到了,事務簡單來說就是一連串的事情,要麼都做,要麼都不做,中間出了問題,整個過程都失敗,對於HTTP事務就是域名解析 --> 發起TCP的3次握手 --> 建立TCP連線後發起http請求 --> 伺服器響應http請求,瀏覽器得到html程式碼 --> 瀏覽器解析html程式碼,並請求html程式碼中的資源--> 瀏覽器對頁面進行渲染呈現給使用者(因為都是這樣說的,所以直接從百度複製貼上過來)。

然後講到了序列事務和並行連線,後者是用多執行緒機制實現,然後講到管道化連線,其實就是流水線,用佇列機制實現,最讓我印象深刻的就是Connection:keep-alive這個首部,以前看過,但總是記不住,所以昨天為了搞清楚一看就是看到凌晨3點。這個首部在HTTP1.0+中支援,預設未啟用,除非客戶端顯式地傳送這個首部,伺服器知道後再決定用不用持久連線,如果伺服器返回了一樣的Connection:keep-alive,客戶端就認為伺服器開了持久連線,如果沒有,客戶端收到響應資料後就會關閉連線,如果想一直保持,那客戶端還得每次都帶上這個首部。

話說到這裡,突然發現跟標題也沒啥關係啊,別急,現在重點來了,以前覺得http長連線和長輪詢要保持住連線應該要用這個首部,然而很顯然我是錯的,這個首部和長連線,長輪詢沒關係,這個首部只是為了減少通訊雙方建立連線的開銷,本質上還是一問(request)一答(response),而且Connection: keep-alive只是是雙方約定長連線、還是收完一次資料後立刻關閉套接字,簡單的說就是HTTP協議的Connection: keep-alive和長連線,長輪詢都是基於socket寫程式碼寫出來的,沒誰一定要用誰。

再說長連線和長輪詢,這兩個是為了實現伺服器push實現的機制,前面說到了,http是一問一答模式,客戶端不發請求伺服器就永遠也不會響應,但是在實時通訊和訊息推送這樣的場景完全不合理啊,伺服器必須一有資料就要發給我,這樣才是實時,為了解決這個問題,所以有很多伺服器push技術。

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

長連線看網上的說法是在頁面裡嵌入一個隱蔵iframe,將這個隱蔵iframe的src屬性設為對一個長連線的請求,伺服器端就能源源不斷地往客戶端輸入資料。其實我也沒看懂,畢竟沒有真的實現過。

現在流行的push技術是websocket,這是一種基於HTTP協議的新協議,實現了全雙工通訊,websocket中不再有主動方和被動方,都是對等方,客戶端和伺服器可以隨時互相傳送資料。

瞎說一大堆,其實就是策略與機制的問題,不同應用場景利用socket的一整套api實現不同功能,但都是雙方規定好才能奏效。還有一點經過本人親身體驗,糾結名詞其實都是基礎不行,所以想真正搞懂這些,趕快去補補基礎吧,《TCP/IP詳解》、《Unix網路程式設計:卷一》走起,多看多練!