I am node beginner and I am trying to set up a multifile image upload through formidable which will have a progress bar and also a callback after each upload which will dynamically load all the images into the same page after they are done uploaded. I understand I need to use socket.io to interact back with the browser after the upload has begun. Formidable has an event listener for "progress". I need my client side script to receive the bytes received to create an upload bar. After the file is done uploading, I want socket.io to pass to the client the url of where the image was uploaded so the client can load the image and append it to the DOM dynamically. Here is the code I have so far.
My question is how do I structure the socket.io code inside the event listener for "progress" so it can broadcast to the client?
Here is some loose pseudo-code to show you what I am talking about:
//formidable code:
app.post('/new', function(req,res){
var form = new formidable.IncomingForm();
form.addListener('progress', function(bytesReceived, bytesExpected){
//Socket.io interaction here??
});
form.uploadDir = __dirname + '/public/images/';
form.on('file', function(field, file) {
//rename the incoming file to the file's name
fs.rename(file.path, form.uploadDir + "/" + file.name);
console.log(form.uploadDir + "/" + file.name);
})
});
//socket.io code
io.sockets.on('connection', function (socket) {
socket.on('upload', function (msg) {
socket.broadcast.emit('progress', bytesReceived);
});
});
I used node-formidable v1.0.14 and socket.io 1.0.0-pre.
When the clients send a request a connection will be made and the server will create a room for this client based on his session id for example.
Afterwards in the progress event we will broadcast the percentage to one client in the room.
Here you can find more info about rooms: https://github.com/LearnBoost/socket.io/wiki/Rooms
Server app.js (main, on startup):
io.on('connection', function (socket) {
console.log('CONNECTED');
socket.join('sessionId');
});
Server POST:
form.on('progress' , function (bytesRecieved , bytesExpected) {
console.log('received: ' + bytesRecieved);
io.sockets.in('sessionId').emit('uploadProgress', (bytesRecieved * 100) / bytesExpected);
});
Client:
var socket = io.connect('http://localhost:9000');
socket.on('uploadProgress' , function (percent){
alert(percent);
});
When you want to work with sessions this might help: http://www.danielbaulig.de/socket-ioexpress/#comment-11315
this should work for you
form.addListener('progress' , function(bytesRecieved , bytesExpected){
io.sockets.on('connection', function (socket) {
socket.emit('uploadProgress', ((bytesRecieved * 100)/bytesExpected));
});
});
and on the client side:
script(src='/socket.io/socket.io.js') // thats jade, but link to the .js anyway you want
var socket = io.connect('http://localhost');
socket.on('uploadProgess' , function(percent){
$('#percent').text(percent);
});