socket.io/连接参数 [英] socket.io / parameters on connection

查看:71
本文介绍了socket.io/连接参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 node.js/Express.js 应用程序中,我需要通过 socket.io 连接传递参数(在另一篇文章中看到).

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 :

编辑

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

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

在服务器端:

编辑

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

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

};

感谢您的帮助

推荐答案

是的,有.

1) query 类似于 GET 参数,因此将 "param:value" 替换为 "param=value"(如果你想传递多个参数,就像你通常对 URL 所做的那样:param=value&some_other_param=test)

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) 在 connection 处理程序中获取查询参数的方法更简单、更可靠(因为没有访问 handshaken 对象的未定义属性的风险):

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

在学习了您的完整代码后,我想我想出了导致问题的原因.问题是你可能误解了 Socket.IO 命名空间的主要思想.

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.

我猜你在一个页面中有多个 Socket.IO 连接(io.connect 调用),对吧?通常一个连接就足够了.你的错误是你在鼠标事件上调用了 io.connect,但是你应该在 document.ready 上调用一次,然后就 emitting.

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

服务端代码:

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

如果你有一个命名空间,它应该可以工作.我实际上不知道这是 Socket.IO 的错误还是命名空间使用不当的结果,但是修改代码以仅创建一个命名空间应该可以解决问题.因此,在您的情况下,您根本不必在握手时传递查询参数. 实际上,如果您想让应用程序更安全,则必须使用查询参数.见 http://wlkns.co/node-js/socket-io-authentication-tutorial-server-and-client/(适用于Socket.io 0.9)

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!

这篇关于socket.io/连接参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆