title: HTTP長連線 date: 2018-09-22 09:59:08 toc: true categories:
- [web前端,HTTP] tags:
- HTTP
長連線的概念
HTTP 的請求是在 TCP 連線的基礎上傳送的,而 TCP連結分為長連線和短連線 。
長連線:HTTP 傳送請求時,要先建立一個 TCP 連線,並在 TCP 連線上把 HTTP 請求的內容傳送並且接收完返回,這是一次請求完成,瀏覽器與伺服器進行協商是否關閉 TCP 連結,若不關閉 TCP 連線會有一定的消耗,好處是如果還有請求可以直接在這個 TCP 連線上傳送,不需要經過建立時三次握手的消耗。
短連線:若關閉 TCP 連線,下次請求需要重新建立,這時會有網路延遲的開銷,好處是每次請求完關閉 TCP 連線,減少客戶端和服務端連線的併發數。
實際情況中,網站的併發量比較大,如果每次都重新建立連線,導致建立過程發生太多,導致建立 TCP 連線的開銷,比保持長連線還要高一些。而且長連線可以設定關閉時間,在一定時間內沒有請求自動關閉。一般情況都會保持長連線。
百度示例
示例,開啟百度首頁,開啟控制檯-network,name那一行,右鍵選中 connection ID,代表 tcp 連線 的 id,根據他區分是否是同一個 tcp 連線。
長連線的使用
命令列 node server.js 啟動服務,locahost:8888訪問,檢視 network的 connection ID 和 waterfall。
設定網速 fast 3G
// server.js
const http = require('http')
const fs = require('fs')
http.createServer(function (request, response) {
console.log('request come', request.url)
const html = fs.readFileSync('test.html', 'utf8')
const img = fs.readFileSync('test.jpg')
if (request.url === '/') {
response.writeHead(200, {
'Content-Type': 'text/html',
})
response.end(html)
} else {
response.writeHead(200, {
'Content-Type': 'image/jpg'
})
response.end(img)
}
}).listen(8888)
console.log('server listening on 8888')
複製程式碼
// test.html
<img src="/test1.jpg" alt="">
<img src="/test2.jpg" alt="">
<img src="/test3.jpg" alt="">
<img src="/test4.jpg" alt="">
<img src="/test5.jpg" alt="">
<img src="/test6.jpg" alt="">
<img src="/test7.jpg" alt="">
<img src="/test11.jpg" alt="">
<img src="/test12.jpg" alt="">
<img src="/test13.jpg" alt="">
<img src="/test14.jpg" alt="">
<img src="/test15.jpg" alt="">
<img src="/test16.jpg" alt="">
<img src="/test17.jpg" alt="">
<img src="/test111.jpg" alt="">
<img src="/test112.jpg" alt="">
<img src="/test113.jpg" alt="">
<img src="/test114.jpg" alt="">
<img src="/test115.jpg" alt="">
<img src="/test116.jpg" alt="">
<img src="/test117.jpg" alt="">
複製程式碼
Chrome瀏覽器的 TCP 連線的併發限制,6個 TCP 連線後,第7個 TCP連線有新的 TCP 連線空出來
預設是長連線
關閉長連線
通過設定 'Connection': 'close' 來關閉預設的長連線。
const http = require('http')
const fs = require('fs')
http.createServer(function (request, response) {
console.log('request come', request.url)
const html = fs.readFileSync('test.html', 'utf8')
const img = fs.readFileSync('test.jpg')
if (request.url === '/') {
response.writeHead(200, {
'Content-Type': 'text/html',
'Connection': 'close' // 預設是 keep-alive
})
response.end(html)
} else {
response.writeHead(200, {
'Content-Type': 'image/jpg',
'Connection': 'close' // 預設是 keep-alive
})
response.end(img)
}
}).listen(8888)
console.log('server listening on 8888')
複製程式碼
沒有重複利用 TCP 連線,並且每個 connection id 都不同
正常情況下都是合理利用 Connection:'keep-alive',並設定一個自動關閉時間,在服務端進行控制
HTTP 2 通道複用
HTTP2 通道複用,在 TCP 連線上可以併發的傳送 HTTP 請求,意味著連結網站是隻需要一個 TCP 連線。google.com的頁面都是用的 HTTP2。
它的 connection id 都是一個,注意,同域 id 才相同,不同域需要建立 tcp 連線,這樣降低了開銷,速度有質的提升。
總結
http 請求是在 tcp 連線上傳送的,一個 tcp 連線可以傳送多個 http 請求
在 http 1.1 中 http 請求在 tcp 上進行傳送有先後順序,為了提高效能,需要使用併發 tcp 連線的方式。
在 http 2 中,可以在一個 tcp 連線上併發的傳送 http 請求,所以只需要開一個 tcp 連線。
長連線的概念