node靜態服務器斷點續傳實現

當用戶從靜態文件服務器上獲取諸如歌曲這樣的流媒體文件時,若是網絡鏈接斷開,重連後未作處理,就須要從新下載這個文件。因此爲了不這種狀況,咱們的服務器須要一種斷點續傳的功能。而http 1.1中正好規定了一種Range機制,咱們能夠經過這種機制來進行分片傳輸。javascript

Range

當一個服務器支持Range時,客戶端能夠將須要發送的內容分紅不少份發送給服務端,服務端能夠每次接收部份內容。有了這樣的能力,遇到斷網的狀況,咱們能夠在客戶端記錄下已經傳送的文件範圍,網絡恢復後再將剩餘部分發送給服務端,這樣就實現了斷點續傳。java

Range的在http 1.1中的具體定義能夠參考文檔:node

具體流程以下:瀏覽器

  • 瀏覽器請求內容。服務器

  • 服務器告訴瀏覽器,該內容可使用 Accept-Ranges 消息頭進行分部分請求。網絡

    response.setHeader('Accept-Ranges', 'bytes');
    複製代碼
  • 瀏覽器從新發送請求,用 Range 消息頭告訴服務器須要的內容範圍。學習

    發送的Range格式:字節數(bytes)= (開始)-(結束)ui

    這是瀏覽器告知服務器所需分部份內容範圍的消息頭. 注意開始和結束位置是都包括在內的,並且是從0開始的. 這個消息頭也能夠不發送兩個位置,其含義以下:spa

    • 若是結束位置被去掉了,服務器會返回從聲明的開始位置到整個內容的結束位置內容的最後一個可用字節。
    • 若是開始位置被去掉了,結束位置參數能夠被描述成從最後一個可用的字節算起能夠被服務器返回的字節數。

而服務器會分以下兩種狀況響應瀏覽器的請求:code

  • 若是範圍是合理的,服務器會返回所請求的部份內容,並帶上 206 Partial Content 狀態碼. 當前內容的範圍會在 Content-Range 消息頭中申明。 發送的Content-Range格式:字節數(bytes)=(開始)-(結束)/(總數)
  • 若是範圍是不可用的(例如,比內容的總字節數大), 服務器會返回 416 請求範圍不合理 Requested Range Not Satisfiable 狀態碼. 可用的範圍也會在 Content-Range 消息頭中聲明。

nodejs簡單實現

getStream(req, res, filepath, statObj) {
    let start = 0;
    let end = statObj.size - 1;
    let range = req.headers['range'];
    if (range) {
        res.setHeader('Accept-Range', 'bytes');
        res.statusCode = 206;
        let result = range.match(/bytes=(\d*)-(\d*)/);
        if (result) {
            start = isNaN(result[1]) ? start : parseInt(result[1]);
            end = isNaN(result[2]) ? end : parseInt(result[2]) - 1;
        }
    }
    return fs.createReadStream(filepath, {
        start, end
    });
}
複製代碼

待續

自我小結

在搭建node靜態服務器過程當中學習利用Http1.1的Range來實現斷點續傳功能

參考資料
相關文章
相關標籤/搜索