2015-03-15 4 views
5

Мне удалось загрузить файлы в куске от клиента к серверу, но теперь я хочу достичь обратного пути. К сожалению, документации на официальной странице модуля нет для этой части.Потоковая передача файла с сервера на клиент с socket.io-stream

Я хочу сделать следующее:

  • испускать поток и «download'-событие с именем файла на сервер
  • сервер должен создать ReadStream и конвейер на поток, испускаемый из клиент
  • , когда клиент достигает потока, загрузка-всплывающее окно появится и спросить, куда сохранить файл

причина, почему я не хочу использовать простой файл-гиперссылок является obfuscati ng: файлы на сервере включены и переименованы, поэтому я должен расшифровать и переименовать их для каждого запроса на загрузку.

Любые фрагменты кода, чтобы начать меня с этого?

+0

Я часто задавался вопросом, зачем передавать потоковые файлы с сервера на клиент через webSocket, когда у HTTP есть поддержка протоколов. Вы можете использовать webSocket для запуска загрузки, указав клиенту URL-адрес, но затем попросите клиента запросить обычный HTTP-поток этого URL-адреса, а не делать это через webSockets. Таким образом, вы сохраняете webSocket бесплатно как систему уведомлений и используете более традиционные потоковые протоколы через http для больших загрузок. – jfriend00

+0

Что говорит jfriend00 – chickenchilli

ответ

12

Это рабочий пример, который я использую. Но почему-то (может быть, только в моем случае) это может быть очень медленным.

//== Server Side 
ss(socket).on('filedownload', function (stream, name, callback) { 

    //== Do stuff to find your file 
    callback({ 
     name : "filename", 
     size : 500 
    }); 

    var MyFileStream = fs.createReadStream(name); 
    MyFileStream.pipe(stream); 

}); 

//== Client Side 
/** Download a file from the object store 
* @param {string} name Name of the file to download 
* @param {string} originalFilename Overrules the file's originalFilename 
* @returns {$.Deferred} 
*/ 
function downloadFile(name, originalFilename) { 

    var deferred = $.Deferred(); 

    //== Create stream for file to be streamed to and buffer to save chunks 
    var stream = ss.createStream(), 
    fileBuffer = [], 
    fileLength = 0; 

    //== Emit/Request 
    ss(mysocket).emit('filedownload', stream, name, function (fileError, fileInfo) { 
     if (fileError) { 
      deferred.reject(fileError); 
     } else { 

      console.log(['File Found!', fileInfo]); 

      //== Receive data 
      stream.on('data', function (chunk) { 
       fileLength += chunk.length; 
       var progress = Math.floor((fileLength/fileInfo.size) * 100); 
       progress = Math.max(progress - 2, 1); 
       deferred.notify(progress); 
       fileBuffer.push(chunk); 
      }); 

      stream.on('end', function() { 

       var filedata = new Uint8Array(fileLength), 
       i = 0; 

       //== Loop to fill the final array 
       fileBuffer.forEach(function (buff) { 
        for (var j = 0; j < buff.length; j++) { 
         filedata[i] = buff[j]; 
         i++; 
        } 
       }); 

       deferred.notify(100); 

       //== Download file in browser 
       downloadFileFromBlob([filedata], originalFilename); 

       deferred.resolve(); 
      }); 
     } 
    }); 

    //== Return 
    return deferred; 
} 

var downloadFileFromBlob = (function() { 
    var a = document.createElement("a"); 
    document.body.appendChild(a); 
    a.style = "display: none"; 
    return function (data, fileName) { 
     var blob = new Blob(data, { 
       type : "octet/stream" 
      }), 
     url = window.URL.createObjectURL(blob); 
     a.href = url; 
     a.download = fileName; 
     a.click(); 
     window.URL.revokeObjectURL(url); 
    }; 
}()); 
Смежные вопросы