4

i have a zip file (15 mb), want to send this to android socket connection, i can able to emit via the following code :

fs.readFile('path',function(err,fileData){
io.to(socketId).emit('sendFile',{'file':fileData.toString('base64')});
});

using the above code, low size file is emitting without any delay, if there is any large size file emitting is delayed. how to achieve this in a better way.

midhun k
  • 1,032
  • 1
  • 15
  • 41
  • 1
    There are practical limits to how large a single message you can send with socket.io/webSockets just like with TCP. I'd suggest you look at the Google search results for "streaming over socket.io" or "streaming over webSocket" and pick one of those solutions. You will ultimately want to send your file in chunks and have those chunks reassembled at the other end and probably use a system that does not require the entire large file to be held in memory at both ends. – jfriend00 Nov 02 '16 at 17:15

1 Answers1

10

You can try to use socket.io-stream like in the below example:

server:

'use strict';
const io = require('socket.io')(3000);
const ss = require('socket.io-stream');
const fs = require('fs');

var filename = 'test.zip';   // 80MB file

io.on('connection', function (socket) {
  console.log('client connected');
  socket.on('sendmeafile', function () {
    var stream = ss.createStream();
    stream.on('end', function () {
        console.log('file sent');
    });
    ss(socket).emit('sending', stream); 
    fs.createReadStream(filename).pipe(stream);
  });  
});

console.log('Plain socket.io server started at port 3000');

client:

'use strict';
const socket = require('socket.io-client')('http://localhost:3000');
const ss = require('socket.io-stream');
const fs = require('fs');

var filename = 'test-copy.zip';

socket.on('connect', function () {
  console.log('connected');
  socket.emit('sendmeafile');
});

ss(socket).on('sending', function(stream) {
  stream.pipe(fs.createWriteStream(filename)); 
  stream.on('end', function () {
    console.log('file received');
  });
});

As jfriend00 wrote in his comment you don't need http.

Abhijit
  • 468
  • 8
  • 22
mk12ok
  • 1,293
  • 14
  • 14
  • 1
    Thanks for your reply, in the above example you are receiving the file on streaming, but in my case file is already in the server, so what i am doing here is fs.readFile from the server and emiting to the destination like : fs.readFile('path',function(err,fileData){ io.to(socketId).emit('sendFile',{'file':fileData.toString('base64')}); }); .... how can i implement the io-stream here? – midhun k Nov 03 '16 at 06:02
  • In my example the file is on the server too and the server sends the stream to the client. The client is also a node app. Do you want to send a file to a browser? – mk12ok Nov 03 '16 at 07:42
  • here my client is android, there is any possibilities? – midhun k Nov 03 '16 at 07:51
  • But... let me understand.. do you have an android client ? Could you please show the client's code? – mk12ok Nov 03 '16 at 08:14
  • 2
    How can I pass the File name or extra data from the server to to client via the pipe – Nyagaka Enock Jul 26 '20 at 12:40
  • Suppose I am sending a file like client1->server->client2, If I pass the stream from client1->server->client2 and do createWriteStream there will it work? – Parag Katoch May 19 '21 at 18:03