2

I need to send file from one client browser to another without having to save it on server (node.js) How am I able to do it with HTML5 and File API?

Actually the solution implemented:

Final solutionlooks like this:

  1. On seeding client get file from input[type=file]

  2. File array contains a key storing file Object. Use slice/mozSlice method to split it chunks so that Object.slice will return Blob object.

  3. Using FileReader Blob can be read into raw binary data or base64 encoded data. FileReader implements readAsDataURL(blob) for reading to base64 and readAsBinaryString(blob) for reading to raw binary data. See 'onloadend' FileReader event to get access to data read from blob.

  4. You should implement logic to calculate chunks number according to chunk size (usually 1024 * 64) and next slice start/stop position to get chunks of exactly same size

  5. Encoded data is sent via socket.io to node.js where the only server-side logic is to send received data to pear also connected through socket.io

  6. Guess most interesting is to get all those chunks together into blob on pear's client browser. Creating Blob from raw binary data will cause the wrong size of blob and in result to wrong file size. That's why we are transfering base64 encoded data from seeder.
    Decoding might become the problem as we must implement it by ourselves.

    function decode64 (data) {
        var mimeString = data.split(',')[0].split(':')[1].split(';')[0],
        // remove all chars before ','
        byteString = atob(data.split(',')[1]),
        // if BlobBuilder available
        ab = new ArrayBuffer(byteString.length),
        ia = new Uint8Array(ab);
    
        for (var i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
        blob    = new Blob([ia], {'type' : (mimeString) });
    return blob;
    }
    

Having decoded data to blob we must push it to array containing aother decoded chunks. 7. Create a Blob from array of chunks decoded to blobs, smth like this

new Blob (array_of_decoded_blobs_returned_by_decode64_function, {type:'mime-type'})

Using file api write blob to file or do whatever you want to do

antiplayer
  • 323
  • 7
  • 15
  • Just found this, you may want to give it a read. http://googleblog.blogspot.sg/2013/02/race-to-win-on-big-and-small-screens.html – Diodeus - James MacFarlane Feb 28 '13 at 22:29
  • This is a super question with a solution!! I've been searching long and hard for something like this. Did you manage to transfer it peer to peer without any relay? I wonder if there is any chance of getting a copy of the code you wrote ?( If it isn't sensitive?) It will be of tremendous help – iAteABug_And_iLiked_it Jun 12 '13 at 11:15
  • and also, in 5 , you are still sending the data to the server,instead of directly to the other peer, consuming ( potentially tons of) bandwidth..how did you get around that ? thanks – iAteABug_And_iLiked_it Jun 12 '13 at 11:25

2 Answers2

2

Websockets are the only way I can imagine doing this, and you'd still need a server-side proxy.

See: Do websockets allow for p2p (browser to browser) communication?

Community
  • 1
  • 1
Diodeus - James MacFarlane
  • 112,730
  • 33
  • 157
  • 176
  • Thanx for your help. Regarding the link you provided, there is no real working implementation for pear to pear with websockets or any other specification. They propose to use server handling connections from different clients, though i have no idea how to transfer file having 2 clients connected through websocket without having to save it on server side. So I need more help – antiplayer Feb 28 '13 at 21:22
  • You may not need to SAVE it on the server, but you may be able to stream through one. – Diodeus - James MacFarlane Feb 28 '13 at 21:25
  • Any ideas on streaming technique with js? I couldn't find a way to upload a file saving to stream or smth like this – antiplayer Feb 28 '13 at 21:36
  • My guess is you'd have to convert it to base64 first. – Diodeus - James MacFarlane Feb 28 '13 at 21:52
  • Solved. Updated the question. Tnx for help @Diodeus – antiplayer Mar 06 '13 at 17:33
1

Check out webrtc. You can directly send file to browser. Server only tells one client browser about an "address" of another client browser.

karaxuna
  • 26,752
  • 13
  • 82
  • 117