2015-05-27 20 views
14

używam PeerJS, ale myślałem, że ten problem może być o WebRTC w ogóle, nadzieję, że można mi pomóc:PeerJS/WebRTC połączenie nie powiedzie się na szybkich kawałków transmittion

Próbuję napisać prosty Peer udostępnianie plików w trybie peer-to-peer. Używam serialisation: "none" dla PeerJS połączenie DataChannel, ponieważ wysyłam tylko czysty ArrayBuffers.
Wszystko jest dobre z plikami około 10mb, ale mam problemy z wysyłaniem większego pliku (30+ mb), na przykład po wysłaniu 10-20 pierwszych fragmentów pliku zip o rozmiarze 900 MB, między równorzędnymi użytkownikami, zaczynają rzucać Connection is not open. You should listen for the "open" event before sending messages. (Po stronie Sender)

Moja konfiguracja:

pliku przeciągać przeciągnąć & spadek, Sender wykorzystuje FileReader go odczytać jako ArrayBuffer w kawałki 64x1024 bajtów (bez różnicy z 16x1024) i tak szybko, jak każda porcja jest czytaj - jest wysyłane za pośrednictwem peer.send (ChunkArrayBuffer).

Reciever tworzy blob z każdej otrzymanej części, po zakończeniu transmisji tworzy kompletną blob z nich i daje link do użytkownika.

Moi rówieśnicze ustawienia połączenia:

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

Moja funkcja wysyłania:

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

Jakieś pomysły co może spowodować to?

Aktualizacja: Ustawianie 50ms Czas oczekiwania pomiędzy transmittions fragmentach pomógł loading bitowy plik 900MB osiągnął 6% (zamiast 1 - 2% poprzednio), zanim zaczął rzucać błędów. Może jest to pewnego rodzaju ograniczenie jednoczesnych operacji poprzez datachannel lub przepełnienie pewnego rodzaju bufora datachannel?
Update1: Oto mój obiekt PeerJS połączenie z DataChannel obiektu wewnątrz niego:
Object visualization in Google Chrome

+2

Miałem ten sam problem w pewnym momencie, ale już go nie mam. Mój kod kończy się na [github] (https://github.com/roberthartung/webrtc_utils/blob/master/example/filetransfer/filetransfer.dart), ale napisany w dart. może to pomaga! Dodałem '{'ordered': true, 'reliable': true}' to' createDataChannel' może to pomaga? – Robert

+0

@Robert niestety to nie pomogło, "uporządkowane" i "wiarygodne" są już prawdziwe w obiekcie 'DataChannel' wewnątrz mojego obiektu' peerjs'. Dodam teraz mój obiekt konsensusu do pytania, czy możesz rzucić tutaj swoje, więc mogę porównać dwa? –

+0

jest link do mojego kodu github. Nie używam peer-a, więc naprawdę nie mogę ci pomóc :(Dla mnie FileReader zajmuje około 25-50ms, aby przekonwertować blob na bytearray i wydaje mi się, że to wystarcza, aby to działało. – Robert

Odpowiedz

8

Good News wszyscy!
To było przepełnienie bufora DataChannel problemu, thx tego artykułu http://viblast.com/blog/2015/2/25/webrtc-bufferedamount/

bufferedAmount jest własnością DataChannel (DC) obiektu, który w najnowszej wersji Chrome wyświetla ilość danych w bajtach, będących aktualnie w buforze, gdy exceedes 16 MB - DC jest cicho zamknięty. Dlatego każdy, kto napotka ten problem, musi wdrożyć mechanizm buforowania na poziomie aplikacji, który będzie obserwował tę właściwość i wstrzymywał wiadomości, jeśli zajdzie taka potrzeba. Należy także pamiętać, że w wersjach Chrome przed 37 ta sama właściwość wyświetla ilość (nie rozmiar) wiadomości, a więcej z nich jest zepsute pod oknami i wyświetla 0, ale z v < 37 na przepełnieniu DC nie jest zamknięty - tylko wyjątek zgłoszony, który może zostać przechwycony w celu wskazania przepełnienia bufora.

I zmienił się peer.js kodu unminified dla siebie, tutaj można zobaczyć obie metody w jednej funkcji (więcej kodu źródłowego można spojrzeć na 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; 
}   
} 

otwarto również problem na PeerJS GitHub: https://github.com/peers/peerjs/issues/291