2015-05-27 14 views
14

sto usando PeerJS, ma pensava che questo problema può essere di circa WebRTC in generale, spero che mi può dare una mano:PeerJS/WebRTC connessione non riesce a pezzi rapidi transmittion

che sto cercando di scrivere un semplice tra pari condivisione di file peer-to-peer. Sto usando serialisation: "none" per la connessione PeerJSDataChannel, poiché sto inviando semplicemente ArrayBuffers.
Tutto è buono con i file intorno a 10mb ma ho problemi nell'invio di file più grandi (30+ mb), ad esempio dopo l'invio di 10-20 primi blocchi di connessione zip 900mb tra peer iniziano a lanciare Connection is not open. You should listen for the "open" event before sending messages. (Sul lato Sender)

mia configurazione:

File trascinato per trascinare & goccia, Sender utilizza FileReader leggere come ArrayBuffer in blocchi di 64x1024 byte (nessuna differenza con 16x1024) e al termine di ogni blocco è leggi - viene inviato tramite peer.send (ChunkArrayBuffer).

Reciever crea blob da ciascun blocco ricevuto, al termine della trasmissione, crea uno blob completo e fornisce un collegamento all'utente.

miei coetanei impostazioni di connessione:

var con = peer.connect(peerid, { 
     label: "file", 
     reliable: true, 
     serialization: "none" 
    }) 

La mia funzione di invio:

function sliceandsend(file, sendfunction) { 
    var fileSize = file.size; 
    var name = file.name; 
    var mime = file.type; 
    var chunkSize = 64 * 1024; // bytes 
    var offset = 0; 

function readchunk() { 
    var r = new FileReader(); 
    var blob = file.slice(offset, chunkSize + offset); 
    r.onload = function(evt) { 
     if (!evt.target.error) { 
      offset += chunkSize; 
      console.log("sending: " + (offset/fileSize) * 100 + "%"); 
      if (offset >= fileSize) { 
       con.send(evt.target.result); ///final chunk 
       console.log("Done reading file " + name + " " + mime); 
       return; 
      } 
      else {      
       con.send(evt.target.result); 
      }    
     } else { 
      console.log("Read error: " + evt.target.error); 
      return; 
     } 
     readchunk(); 
     }; 
     r.readAsArrayBuffer(blob); 
    } 
    readchunk(); 
    } 

Delle idee che cosa può causare questo?

Aggiornamento: Impostazione di 50 ms Il timeout tra le trasmissioni di chunk ha aiutato un po ', il caricamento di file di 900mb ha raggiunto il 6% (anziché 1 - 2% in precedenza) prima di iniziare a generare errori. Forse è una sorta di limite delle operazioni simultanee attraverso datachannel o traboccare qualche tipo di buffer datachannel?
Update1: Ecco il mio oggetto PeerJS connessione con DataChannel oggetto al suo interno:
Object visualization in Google Chrome

+2

ho avuto lo stesso problema a un certo punto, ma non hanno più. Il mio codice è finito a [github] (https://github.com/roberthartung/webrtc_utils/blob/master/example/filetransfer/filetransfer.dart) ma scritto in dart. forse aiuta! Ho aggiunto '{'ordered': true, 'reliable': true}' to 'createDataChannel' forse aiuta? – Robert

+0

@Robert purtroppo questo non ha aiutato, 'ordinato' e 'affidabile' sono già veri nell'oggetto 'DataChannel' all'interno del mio oggetto conencisione' peerjs'. Ora aggiungerò il mio oggetto conenction alla domanda, puoi buttare il tuo qui, quindi posso confrontare due? –

+0

c'è un link al mio codice github. Non sto usando peerjs quindi non posso aiutarti molto qui :(Per me FileReader richiede ~ 25-50ms per convertire il blob in bytearray e sembra che questo sia sufficiente per farlo funzionare per me. – Robert

risposta

8

Buona Novella a tutti!
Era un buffer overflow di DataChannel problema, thx a questo articolo http://viblast.com/blog/2015/2/25/webrtc-bufferedamount/

bufferedAmount è una proprietà di DataChannel (DC) oggetto nell'ultima versione Chrome mostra quantità di dati in byte che sono attualmente in tampone, quando exceedes 16 MB - DC è chiuso silenziosamente. Pertanto, chiunque incontrerà questo problema dovrà implementare il meccanismo di buffering a livello dell'applicazione, che controllerà questa proprietà e manterrà i messaggi se necessario. Inoltre, si tenga presente che nelle versioni di 37 la stessa proprietà visualizza la quantità (non la dimensione) dei messaggi, e più è rotto in Windows e visualizza 0, ma con v < 37 su overflow DC non è chiuso - solo eccezione generata, che può anche essere catturata per indicare overflow del buffer.

ho fatto una modifica in peer.js codice unminified per me, qui potete vedere entrambi i metodi in una funzione (per maggiori del codice sorgente si può guardare https://github.com/peers/peerjs/blob/master/dist/peer.js#L217)

DataConnection.prototype._trySend = function(msg) { 
var self = this; 
function buffering() { 
    self._buffering = true; 
    setTimeout(function() { 
     // Try again. 
     self._buffering = false; 
     self._tryBuffer(); 
    }, 100); 
    return false; 
} 
if (self._dc.bufferedAmount > 15728640) { 
    return buffering(); ///custom buffering if > 15MB is buffered in DC 
} else { 
    try { 
     this._dc.send(msg); 
    } catch (e) { 
     return buffering(); ///custom buffering if DC exception caught 
    } 
    return true; 
}   
} 

anche aperto un problema su PeerJS GitHub: https://github.com/peers/peerjs/issues/291