socket.io / 连接参数

Posted

技术标签:

【中文标题】socket.io / 连接参数【英文标题】:socket.io / parameters on connection 【发布时间】:2014-09-24 20:29:44 【问题描述】:

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

在客户端,我有类似的东西:

编辑

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

但控制台中什么也没有。

还有其他方法可以实现吗?

edit2

这是客户端的完整代码:

$(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

以及服务器端的完整代码:

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

;

感谢您的帮助

【问题讨论】:

如果控制台中没有任何内容,您的connection 处理程序根本不会触发,因为至少undefined 应该在控制台中。可能您在其他地方有错误以及我在回答中描述的错误。 您的代码似乎在工作,除了一件事:您声明 socket,但将 socket2 传递给 SocketIOFileUpload 构造函数。 是的,对不起,在我的代码中,套接字的真实名称是`socket2。但正如我在你的回答中所说,这段代码是在我想要之前执行的......它是在我启动服务器时执行的。而此时,包含socket代码的客户端文件并没有被包含... 我相信它是在服务器启动时执行的,因为您的浏览器中有一个打开的页面,并且 Socket.IO 尝试重新连接每个n 秒。当服务器启动时,重新连接成功并且您的connection 处理程序触发(通常在客户端和服务器之间的连接成功建立时触发)。奇怪的是console.log 输出underfined。我尝试了您的代码,对我来说,Socket.IO 0.9 和 1.0 都可以正常工作。你能展示你的完整代码吗,因为我认为问题出在其他地方。 你试过socket.io文件上传模块了吗?也许问题出在这个包上……我使用的是 socket.io 0.9。请看帖子更新。我添加了完整的客户端 - 服务器代码。我没有添加 HTML 部分。它只是通过单击要更改的图像打开的模式窗口。 &lt;a title="Icon Actions" class="icon_actions" data-toggle="modal" href="#icon_action_modal" data-icon="&lt;%= icon %&gt;"&gt;。 TY 为您提供帮助 【参考方案1】:

是的,有。

1) query 类似于GET 参数,因此将"param:value" 替换为"param=value"(如果要传递多个参数,请按照通常使用URL 的方式进行操作:param=value&amp;some_other_param=test

2) 在connection 处理程序中获取查询参数有一种更简单、更可靠(因为没有访问handshaken 对象的未定义属性的风险)的方法:

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

编辑:

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

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

看看下面的代码(客户端):

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

希望我的回答对你有所帮助。祝你好运!

【讨论】:

Ty 为您的回答 CuriousGuy。它没有解决我的问题,但 Ty 用于解释“查询”参数。我使用 socket.io file-upload 在我的网络服务器上上传一些图像。在“更新”情况下,我需要检索图像名称以将其分配到新图像上。在我的控制台中,我看到我的套接字上的连接是在我的图像更新操作之前。日志说,log input param : undefined 但此时,我还没有加载新图像......请看我的帖子更新。提前为您提供帮助 +1 ! Ty 为您的时间和您非常完整的答案。如果query 参数不起作用,您的解决方案是我的第二选择。我会朝那个方向走。 TY好奇的家伙! @Curious:如何通过查询选项传递 2 个参数?提前致谢! @Pritam 你试过这个:query: 'param1=something&amp;param2=another' 吗?您可以像使用 URL GET 参数一样传递参数,即使用 &amp; 作为分隔符 @span 是我的错误。 socket'connection' 处理函数参数。编辑了我的答案。谢谢你:)【参考方案2】:

这就是我所做的。

客户

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

服务器

io.on('connection', function (socket) 
  console.log(socket.handshake.query['foo']);
); 

【讨论】:

这是完美的 应该是这样的。很棒(Y) 为什么这对我不起作用,你在这里使用的是什么版本的 socket.io? v4 你可以使用这个:var socket = io('http://localhost:8890', query: "foo=bar" );【参考方案3】:

2021 年(socket.io 版本 4)

// client.js

const socket = io('https://195.174.3.104:3000',  query:  myParam: 'myValue'  );
// server.js

io.on("connection", (socket) => console.log(socket.handshake.query.myParam);  // myValue

来源:https://socket.io/docs/v4/client-initialization/#query

【讨论】:

socket.io/docs/v4/client-options/#query

以上是关于socket.io / 连接参数的主要内容,如果未能解决你的问题,请参考以下文章

Socket.io 事件列表

记一次socket.io的debug记录

( Socket.io ) 一个socket连接多个房间

Socket.io node.js,如何避免记录连接时间或考虑页面刷新/多个套接字?

android studio连接io.socket:sokect.io-client服务器的条件

socket io:如何传递参数来断开套接字事件?