Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

socket.io / parameters on connection

In my node.js / Express.js app, I need to pass parameters with the socket.io connection (saw that in another post).

On client side, I have something like :

edit

var socket = io.connect('/image/change', {query:"name=my_img_name"}); var siofu = new SocketIOFileUpload(socket);  siofu.listenOnInput(document.getElementById("change_image_inpt")); 

On server side :

edit

io.of('/image/change')   .on('connection', function (socket) {   console.log('log input param : ' + socket.handshake.query.name); }); 

But nothing in the console.

Is there another way to achieve that ?

edit2

This is the full code for client :

$(document).ready(function() {  // icon_action_modal $('.icon_actions').on('click', function() {     // set icon preview     $('#icon_action_modal_icon_preview').html('<img src="/upload/icon/' + $(this).data('icon') + '.png" />');      // set icon to delete     $('#icon_name').val($(this).data('icon'));      // set Change icon socket     var socket = io.connect('/icon_sets/change', {query:"name=my_img_name"});     var siofu = new SocketIOFileUpload(socket);      siofu.listenOnInput(document.getElementById("change_icon"));      // Do something when a file is uploaded     siofu.addEventListener("complete", function () {         $('.overlay').hide();     });      // display loader window     socket.on('displayOverlay', displayOverlay);      // display     socket.on('displayIconImage', function (data) {         $('#iconset_render').append('<div class="icon"><img src="' + data.path + '" /></div>');     });      socket.on('setIconsetArray', function (data) {         var iconset = ($('#iconset_array').val()) ? JSON.parse($('#iconset_array').val()) : [];          iconset.push(data.iconName);          $('#iconset_array').val(JSON.stringify(iconset));          deleteIcon($('#icon_name').val());          // close modal         $('#icon_action_modal').modal('hide');     });  });  $('#icon_action_modal_delete_icon').on('click', function() {     deleteIcon($('#icon_name').val());      // close modal     $('#icon_action_modal').modal('hide'); });  }); // end document.ready 

And the full code for server side :

io.of('/icon_sets/change')   .on('connection', function (socket) {     console.log('log input param : ' + socket.handshake.query.name);     functions.socketImageTransfer(socket, 'icon', 65, 65); }); 

With the socketImageTransfer function :

module.exports.socketImageTransfer = function(socket, type, width, height, name) {  var socketioFileUploadServer    = require('socketio-file-upload');   // upload files by socket var config                      = require(__dirname + '/config/config.json'); var easyimg                     = require('easyimage');                 // crop - resize image var fs                          = require('fs');                        // file system access  // Make an instance of socketioFileUploadServer and listen on this socket: var uploader = new socketioFileUploadServer(); uploader.dir = config.tmpDir; uploader.listen(socket);  // Do something when a file is saved: uploader.on('saved', function (event) {      console.log('Original ' + type + ' saved');      // resize and rename image with a unique id     var newName;      if (!name) {         newName = Math.random().toString(36).substr(2, 9) + '_' + type + '.png';     } else {         newName = name;     }      var fileName = event.file.name.replace(/ /g, '_');      easyimg.rescrop({src: config.tmpDir + fileName, dst: config.uploadDir + type + '/' + newName, width: width, height: height}, function (err, image) {          if (err) return console.log(err);          console.log(type + ' resized and cropped: ' + image.width + ' x ' + image.height);          // image is uploaded - resized - croped, now display it         socket.emit('display' + ucfirst(type) + 'Image', {path: '/upload/'+ type + '/' + newName});          // remove original from file system         fs.unlink(config.tmpDir + fileName, function () {             if (err) throw err;             console.log('Original ' + type + ' removed');         });          // additionnal action         switch(type) {             case 'icon':                 // send path to generate iconset_json                 socket.emit('setIconsetArray', {iconName: newName});                 break;         }      });  });  uploader.on('start', function (event) {     console.log('Client start upload');     socket.emit('displayOverlay'); });  // Error handler: uploader.on('error', function (event) {     console.log("Error from uploader", event); });  }; 

Appreciate your help

like image 972
ceadreak Avatar asked Aug 01 '14 15:08

ceadreak


People also ask

How do I secure a socket IO connection?

All you have to do is updating the remote session store on node server when a new login/logout happens in your php server. Show activity on this post. The excellent passport framework for express uses secure cookies to validate identity. There is even a module to access it from socket.io.

How does socket IO connection work?

Socket.IO allows bi-directional communication between client and server. Bi-directional communications are enabled when a client has Socket.IO in the browser, and a server has also integrated the Socket.IO package. While data can be sent in a number of forms, JSON is the simplest.

Is socket IO TCP connection?

The Socket.IO library keeps an open TCP connection to the server, which may result in a high battery drain for your users.


2 Answers

Yes, there is.

1) query is like GET parameters, so replace "param:value" with "param=value" (if you want to pass multiple parameters, do it as you usually do with URL: param=value&some_other_param=test)

2) There is an easier and more reliable (because there is no risk to access an undefined property of handshaken object) way to get query parameter inside connection handler:

console.log(socket.handshake.query.param); 

Edit:

After learning your full code I guess I figured out what causes the problem. The problem is that you probably misunderstood the main idea of Socket.IO namespaces.

I guess you have multiple Socket.IO connections (io.connect calls) within one page, right? Usually a single connection is enough. Your mistake is that you call io.connect on mouse event, but you should call in once on document.ready, and then just emitting.

Take a look at the following code (client side):

$(document).ready(function() {     var socket = io.connect('', {query: 'name=something'});      // [...]      socket.on('some_event_from_server', function(data, cb) {});      // [...]      $('#someButton').click(function() {         socket.emit('markers_add', {some: 'data'});  //send `markers_add` message to server within main namespace     });      $('#someOtherButton').click(function() {         socket.emit('icon_sets_add', {some: 'thing'}, function(response) {             //server may response to this request. see server side code below         });     }); }); 

Server side code:

io.on('connection', function(socket) {  //connection handler of main namespace     socket.on('markers_add', function(data) { /* ... */  });     socket.on('icon_sets_add', function(data, cb) {         // do something         cb({some: 'response'});     });      // [...]      socket.emit('some_event_from_server', {});  //server sends a message to a client      //BTW, now it should be OK:     console.log(socket.handshake.query.name); }); 

If you have one namespace it should work. I don't know actually if it was a bug of Socket.IO or a result of improper usage of namespaces, but modifying code to make just one namespace should do the trick. So in your case you don't have to pass query parameters when handshaking at all. Actually you have to use query parameter if you want to make your app more secure. See http://wlkns.co/node-js/socket-io-authentication-tutorial-server-and-client/ (for Socket.io 0.9)

Hope my answer helps you. Good luck!

like image 124
Oleg Avatar answered Sep 29 '22 09:09

Oleg


Here's what I've done.

Client

var socket = io.connect('http://localhost:8890',{ query: "foo=bar" }); 

Server

io.on('connection', function (socket) {   console.log(socket.handshake.query['foo']); });  
like image 22
Marlon Bernal Avatar answered Sep 29 '22 10:09

Marlon Bernal