<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] # 持久連接 HTTP請求都要經過TCP三次握手建立連接,四次分手斷開連,如果每個HTTP請求都要建立TCP連接的話是極其費時的。 <br> 請求頭中的 `Connection: keep-alive` 的作用可以在請求完成后,保持TCP連接一段時間而不關閉,如果這個期間又有HTTP請求的話,直接使用這個TCP連接,省去了建立新的連接的時間。 <br> HTTP/1.1中瀏覽器默認開啟了`Connection: keep-alive`。服務端可以設置 `Connection: close` 來關閉持久連接。 <br> 通過設置 `timeout `,一定時間后在此 TCP 連接沒有請求就會關閉。 <br> 同時服務端還會設置一個參數叫最大請求數,比如當最大請求數是300時,只要請求次數超過300次,即使還沒到超時時間,服務端也會主動關閉連接。 <br> 不同 ID 代表不同的 TCP 連接。不同域名需要分別創建 TCP連接。 TCP 請求的連接有先后順序,無法并發執行。瀏覽器允許并發創建 TCP,如Chrome 允許最多6個并發。 ![](https://box.kancloud.cn/e289ffdfc051e6e77e3410f85745a6ec_1899x456.png) <br> ## 好處 大大減少了連接的建立以及關閉時延。 ![](https://box.kancloud.cn/b9e19e46ce0d352becf0f2f90e44c771_912x304.png) 如圖:多個請求響應在一條連接內完成了。但是,這里也看出一個“缺點”,請求響應是順序執行的。只有在請求1的響應收到之后,才會發送請求2,這就是持久連接與管道化連接不同的地方。 ## 信道復用 在HTTP2里面有個**信道復用**的概念,在TCP/IP連接上面,可以并發的發送HTTP請求。在我們連接網站的時候,只需要一個TCP連接。 如果不同域,則會有多個TCP連接。 ![](https://box.kancloud.cn/9435da4b4075b664643a8956445397fc_1909x486.png) # 例子 ## 瀏覽器 ### 持久連接 body.js ~~~ <body> <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=""> </body> ~~~ <br> server.js ~~~ const http = require('http') const fs = require('fs') http.createServer(function (req, res) { console.log(`requeset come ${req.url}`) const html = fs.readFileSync('index.html', 'utf8') const img = fs.readFileSync('test.jpg') if (req.url === '/') { res.writeHead(200, { 'Content-type': 'text/html', // 'connection': 'close' // 非持久連接 }) res.end(html) } else { res.writeHead(200, { 'Content-type': 'image/jpg', // 'connection': 'close' // 非持久連接 }) res.end(img) } }).listen(8888) console.log('server listen on 8888') ~~~ ![](https://box.kancloud.cn/431e6e6c03c2520bff6267d971cd2dda_1903x514.png) 分析: * 第一張圖片 test1.jpg需要等 html 解析完才能加載,因此使用同一個 TCP 連接 * test1.jpg 到 test6.jpg 為并發請求,從Waterflow可以看出。connection ID不同。 * Chrome 只能并發創建6個 TCP 連接,因此 test7.jpg 只能等任意一個連接完成后才能加載 ### 非持久連接 反注釋上一節代碼的 `'connection': 'close'` ![](https://box.kancloud.cn/1c49308aee785b84f37610c9fe1de878_1899x483.png) <br> 分析: * 所有請求的connection ID 都不同 ## Node ### 串行請求(不使用keep-alive) ~~~ let request = require('request'); ;(async function fn() { for (let i = 0; i < 10; i ++) { await new Promise((resolve, reject) => { request({ method: 'GET', uri: 'http://localhost:8887/a', time: true, // 配置這個屬性可以看到時間信息 // forever: true }, (error, response, body) => { console.log('timingPhases', response.timingPhases); resolve(); }); }); } return 'success'; })() ~~~ ![](https://box.kancloud.cn/e01648dbd5edecd373160f4ba6e81b95_495x670.png) ### 串行請求(使用keep-alive) ~~~ let request = require('request'); ;(async function fn() { for (let i = 0; i < 10; i ++) { await new Promise((resolve, reject) => { request({ method: 'GET', uri: 'http://localhost:8887/a', time: true, // 配置這個屬性可以看到時間信息 forever: true }, (error, response, body) => { console.log('timingPhases', response.timingPhases); resolve(); }); }); } return 'success'; })() ~~~ ![](https://box.kancloud.cn/fc0b959bc298894cce5b44e11c19aa77_551x749.png) ### 并行請求 HTTP/1.1并行請求的時候會建立多個TCP連接,在瀏覽器中針對同一域名只可以同時建立6個連接,Node中沒有這個限制 ~~~ let request = require('request'); ;(async function fn() { let promiseArr = []; for (let i = 0; i < 10; i ++) { let newP = new Promise((resolve, reject) => { request({ method: 'GET', uri: 'http://localhost:8887/a', time: true, forever: true }, (error, response, body) => { console.log('timingPhases', response.timingPhases); resolve(); }); }); promiseArr.push(newP); } Promise.all(promiseArr) })() ~~~ ![](https://box.kancloud.cn/ccb867bf0092b96166fb37d3b703703d_490x828.png) ![](https://box.kancloud.cn/b9987872cce7e3f684cfc0bad8e5cd6e_783x285.png) <br> <br> # 參考資料 [HTTP總結(六):長連接](https://zhuanlan.zhihu.com/p/57142432) [長連接及在Node中的應用——HTTP/1.1 keep-alive](https://juejin.im/post/5c7b1be9f265da2dac4568a2)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看