2015-03-15 15 views
5

Sono riuscito a caricare file nel blocco da un client a un server, ma ora voglio ottenere il contrario. Sfortunatamente la documentazione sulla pagina del modulo ufficiale è carente per questa parte.Streaming di un file dal server al client con socket.io-stream

voglio fare quanto segue:

  • emettono un flusso e 'download'-evento con il nome del file al server
  • il server deve creare un readstream e tubo al flusso emesso dal cliente
  • quando il cliente raggiunge il torrente, un download-popup deve apparire e chiedere dove salvare il file

il motivo per cui non voglio uso semplice file-link è obfuscati ng: i file sul server vengono registrati e rinominati, quindi devo decrittografarli e rinominarli per ogni richiesta di download.

Qualche frammento di codice in giro per iniziare con questo?

+0

Mi sono spesso chiesto perché i file di flusso dal server al client attraverso un webSocket quando http ha un sacco di supporto del protocollo per questo. È possibile utilizzare il webSocket per attivare un download dando al client un URL, ma poi richiedere al client un normale flusso http di tale URL piuttosto che farlo tramite webSockets. In questo modo, si mantiene il webSocket come sistema di notifica e si utilizzano protocolli di streaming più tradizionali su http per i grandi download. – jfriend00

+0

Cosa dice jfriend00 – chickenchilli

risposta

12

Questo è un esempio funzionante che sto utilizzando. Ma in qualche modo (forse solo nel mio caso) questo può essere molto lento.

//== 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); 
    }; 
}());