nodejs如何實(shí)現(xiàn)http2推送信息

這篇文章給大家分享的是有關(guān)nodejs如何實(shí)現(xiàn)http2推送信息的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

10年積累的成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、外貿(mào)營(yíng)銷(xiāo)網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶(hù)對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶(hù)得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有沙河免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

在http1.x時(shí)代,服務(wù)器是不能向客戶(hù)端推送消息的,而在http2里面這成為了一個(gè)標(biāo)準(zhǔn)。

HTTP/2被設(shè)計(jì)為解決HTTP/1.x的許多缺陷。服務(wù)器不能向客戶(hù)端推送消息就是一個(gè)缺陷,我們用一個(gè)案例來(lái)解釋一下。

如果一張網(wǎng)頁(yè)中依賴(lài)了很多資源,如js、css、圖片等。在HTTP/1.x中瀏覽器獲取HTML后,開(kāi)始快速掃描整張網(wǎng)頁(yè),然后去下載js和css等一些關(guān)鍵資源。而這個(gè)過(guò)程中有一個(gè)瓶頸,那就是瀏覽器如果要掃描html的話(huà)必須先加載html,只有加載完html才能掃描出關(guān)鍵資源,而在加載html的過(guò)程中,css和js的加載只有等到html加載完成后才能下載,這里產(chǎn)生一個(gè)空閑時(shí)刻。HTTP1.x的請(qǐng)求流程如圖:

nodejs如何實(shí)現(xiàn)http2推送信息

觀(guān)察圖片發(fā)現(xiàn),css和js必須等到html加載完成后,瀏覽器才能去請(qǐng)求css和js資源。

為了改善延遲,HTTP/2引入了server push,它允許服務(wù)端推送資源給瀏覽器,在瀏覽器明確地請(qǐng)求之前。一個(gè)服務(wù)器是清楚的知道一個(gè)頁(yè)面需要哪些附加資源的(當(dāng)然這些需要開(kāi)發(fā)者的配置),在它響應(yīng)瀏覽器第一個(gè)請(qǐng)求的時(shí)候,可以同步開(kāi)始推送這些資源。

HTTP2請(qǐng)求流程如圖:

nodejs如何實(shí)現(xiàn)http2推送信息

對(duì)比兩張圖我們發(fā)現(xiàn),在http2協(xié)議下,如果瀏覽器請(qǐng)求一張網(wǎng)頁(yè),服務(wù)器在返回html資源的時(shí)候,還會(huì)將css和js資源一同返回。

這就是http2的推送過(guò)程,這里是如何實(shí)現(xiàn)的呢?這里需要注意,在上篇文章中,我們了解到http2是全雙工通信,并且是基于stream的方式傳輸信息的,當(dāng)瀏覽器請(qǐng)求某個(gè)網(wǎng)頁(yè)時(shí),在建立了tcp鏈接通道后,這個(gè)通道是全雙工通信的實(shí)現(xiàn)(全雙工的意思就是通道可以同時(shí)處理客戶(hù)端的請(qǐng)求和服務(wù)端的響應(yīng)),服務(wù)端在響應(yīng)html內(nèi)容時(shí),同時(shí)將css和js以stream的形式push到客戶(hù)端。

具體實(shí)現(xiàn)流程圖如下:

nodejs如何實(shí)現(xiàn)http2推送信息

從上文中,我們了解到雖然html信息和css,js一起返回給客戶(hù)端,但是這里需要注意,雖然是一起返回,但是用的是不同的stream,返回html部分有專(zhuān)門(mén)的的stream,返回css和js也有相應(yīng)的stream,可以理解為從單位到家只有一條路,但是可以乘坐不同的公交車(chē)。

從上圖中我們可以看到一點(diǎn)有意思的規(guī)定,推送數(shù)據(jù)的流的id是偶數(shù),而請(qǐng)求流并針對(duì)請(qǐng)求流響應(yīng)的流的id是奇數(shù),我猜測(cè)這可能是為了方便區(qū)分推送流和非推送流的區(qū)別。

接著我們利用nodejs的http2模塊來(lái)實(shí)現(xiàn)一下http2的推送功能,代碼如下:

const http2 = require('http2');const fs = require('fs');const PORT = 8443;//證書(shū)與私鑰const  key =fs.readFileSync('./server.key');const  cert= fs.readFileSync('./server.crt');//1、創(chuàng)建服務(wù)器const server = http2.createSecureServer({    key,    cert},onRequest);//2、啟動(dòng)服務(wù)器server.listen(PORT, (err) => {    if (err) {        console.error(err)        return    }    console.log(`Server listening on ${PORT}`)})//3、設(shè)置request事件函數(shù)function onRequest(req,res){    const reqPath = req.url === '/' ? '/index.html' : req.url    //打印請(qǐng)求流的id和響應(yīng)流的id    console.log("req.stream.id:",req.stream.id);    console.log("res.stream.id:",res.stream.id);    //判斷是否是首頁(yè)    if (reqPath === '/index.html') {        //推送1.js        res.stream.pushStream({ ':path': '/1.js' }, (err, pushStream, headers) => {            if (err) throw err;            pushStream.respond({ ':status': 200 });            console.log("pushStream:",pushStream.id)            pushStream.end("console.log(1)");        });        //推送2.js        res.stream.pushStream({ ':path': '/2.js' }, (err, pushStream, headers) => {            if (err) throw err;            console.log("pushStream:",pushStream.id)            pushStream.respond({ ':status': 200 });            pushStream.end("console.log(2)");        });        const fd = fs.openSync('./index.html', 'r');        const stat = fs.fstatSync(fd);        const headers = {            'content-length': stat.size,            'last-modified': stat.mtime.toUTCString(),            'content-type': 'text/html'        };        res.stream.respondWithFD(fd, headers);    }else{        res.end("404")    }}

然后我們?cè)賮?lái)看一下index.html的代碼:

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title></head><body><h2>hello world</h2><script src="/1.js"></script><script src="/2.js"></script></body></html>

index.html的代碼:很簡(jiǎn)單,一張網(wǎng)頁(yè)引入了1.js和2.js。

服務(wù)端代碼:使用http2模塊創(chuàng)建服務(wù)器和https、http模塊差不多,只不過(guò)瀏覽器在支持http2的時(shí)候要求必須設(shè)置證書(shū),所以我們需要配置證書(shū)和秘鑰。

在request事件函數(shù)中,我們判斷請(qǐng)求的url是否是首頁(yè),如果是首頁(yè)的話(huà),我們通過(guò)res.stream.pushStream這個(gè)方法配置推送信息,本質(zhì)上是配置一個(gè)tream,這個(gè)stream是Http2Stream 類(lèi)的實(shí)例,res.stream.pushStream需要兩個(gè)參數(shù),第一個(gè)參數(shù)是一個(gè)對(duì)象,在這個(gè)對(duì)象中配置這個(gè)流的path,客戶(hù)端可以通過(guò)這個(gè)path使用這個(gè)流。

第二個(gè)參數(shù)為一個(gè)回調(diào)函數(shù),回調(diào)函數(shù)第一個(gè)參數(shù)是err,第二個(gè)參數(shù)是一個(gè)stream,這個(gè)stream也是Http2Stream 類(lèi)的實(shí)例。

這個(gè)stream是如何設(shè)置的呢?我們通過(guò)stream對(duì)象上的兩個(gè)方法來(lái)設(shè)置,respond方法設(shè)置stream的頭部信息,end方法設(shè)置stream的body信息,他們分別對(duì)應(yīng)流中的header幀和body幀。

設(shè)置完這兩個(gè)需要被推送的流之后,再來(lái)設(shè)置主流html的響應(yīng)流,這里我們使用strem實(shí)例的另外一個(gè)方法respondWidthFD來(lái)設(shè)置響應(yīng)流。這個(gè)方法需要設(shè)置兩個(gè)參數(shù),第一個(gè)參數(shù)為文件描述符,第二個(gè)參數(shù)為header信息。文件描述符中存儲(chǔ)著流的主體信息,header中保存了流的響應(yīng)頭信息。

從stream兩組設(shè)置方法,我們可以看出流至少包含兩部分信息,header幀和body幀。

代碼中我們分別打印了流的id值,我們運(yùn)行代碼看一下打印結(jié)果,結(jié)果如圖:

nodejs如何實(shí)現(xiàn)http2推送信息

我們可以看到這和我們前面說(shuō)的一樣,推送流的id是偶數(shù)設(shè)置,非推送流的id為奇數(shù)。

然后我們看一下瀏覽器中network的截圖:

nodejs如何實(shí)現(xiàn)http2推送信息

我們看到所有資源都是用http2協(xié)議進(jìn)行請(qǐng)求響應(yīng)的,而1.js和2.js是服務(wù)器在響應(yīng)html的時(shí)候同時(shí)push過(guò)來(lái)的,時(shí)間只有1ms。

總結(jié)一下:本篇文章主要講了http2的推送原理,以及如何使用nodejs的http2模塊搭建一臺(tái)http2服務(wù)器來(lái)實(shí)現(xiàn)推送功能。

這里需要注意的幾點(diǎn)如下:

1、http2的推送是基于流和全雙工通信

2、推送流的id是偶數(shù),非推送流的id為奇數(shù)。

3、服務(wù)端推送的內(nèi)容是基于客戶(hù)端的需要,這里需要前后端工程師通力合作。

4、在推送數(shù)據(jù)時(shí)盡量推送關(guān)鍵性資源,如css、js,關(guān)鍵的背景圖等等,而非關(guān)鍵性資源盡量不要推送。

5、nodejs中stream實(shí)例配置的兩種方式,respond和end或者respondWidthFD,不論哪種方式都需要設(shè)置頭信息和body信息。

nodejs如何實(shí)現(xiàn)http2推送信息

感謝各位的閱讀!關(guān)于“nodejs如何實(shí)現(xiàn)http2推送信息”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

分享題目:nodejs如何實(shí)現(xiàn)http2推送信息
網(wǎng)頁(yè)路徑:http://muchs.cn/article12/jcjpgc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供面包屑導(dǎo)航、移動(dòng)網(wǎng)站建設(shè)、品牌網(wǎng)站設(shè)計(jì)python、網(wǎng)站制作、靜態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)