web-dev-qa-db-fra.com

socket.io / paramètres sur la connexion

Dans mon application node.js/Express.js, je dois passer des paramètres avec la connexion socket.io (vu cela dans un autre post).

Côté client, j'ai quelque chose comme:

modifier

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

siofu.listenOnInput(document.getElementById("change_image_inpt"));

Côté serveur:

modifier

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

Mais rien dans la console.

Y a-t-il un autre moyen d'y parvenir?

edit2

Ceci est le code complet pour le 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

Et le code complet côté serveur:

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

Avec la fonction socketImageTransfer:

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

};

Apprécier ton aide

12
ceadreak

Oui il y a.

1) query est comme les paramètres GET, donc remplacez "param:value" avec "param=value" (si vous voulez passer plusieurs paramètres, faites-le comme vous le faites habituellement avec l'URL: param=value&some_other_param=test)

2) Il existe un moyen plus simple et plus fiable (car il n'y a aucun risque d'accéder à une propriété non définie de l'objet handshaken) d'obtenir le paramètre de requête dans le gestionnaire connection:

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

Modifier:

Après avoir appris votre code complet, je suppose que j'ai compris ce qui cause le problème. Le problème est que vous avez probablement mal compris l'idée principale des espaces de noms Socket.IO.

Je suppose que vous avez plusieurs connexions Socket.IO (io.connect appels) sur une seule page, non? Habituellement, une seule connexion suffit. Votre erreur est que vous appelez io.connect lors d'un événement avec la souris, mais vous devez appeler une seule fois le document.ready, puis juste emitting.

Jetez un œil au code suivant (côté client):

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

Code côté serveur:

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

Si vous avez un espace de noms, cela devrait fonctionner. Je ne sais pas vraiment si c'était un bogue de Socket.IO ou le résultat d'une mauvaise utilisation des espaces de noms, mais la modification du code pour créer un seul espace de noms devrait faire l'affaire. Donc, dans votre cas, vous n'avez pas du tout à transmettre de paramètres de requête lors de l'établissement d'une liaison. En fait, vous devez utiliser le paramètre de requête si vous souhaitez rendre votre application plus sécurisée. Voir http://wlkns.co/node-js/socket-io-authentication-tutorial-server-and-client/ (pour Socket.io 0.9)

J'espère que ma réponse vous aidera. Bonne chance!

33
Oleg

Voici ce que j'ai fait.

Client

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

Serveur

io.on('connection', function (socket) {
  console.log(socket.handshake.query['foo']);
}); 
18
Marlon Bernal