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

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

问题描述

在我的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 ',function(socket){
console.log('log input param:'+ socket.handshake.query.name);
});

但在控制台中没有任何内容。



还有另一种方法来实现吗?



edit2



这是完整的客户端代码:

  $(document).ready(function(){

// icon_action_modal
$('。icon_actions')。on('click',function(){
//设置图标预览
$('#icon_action_modal_icon_preview')。html('< img src =/ upload / icon /'+ $(this).data('icon')+'.png/>');

//设置图标删除
$ ('#icon_name')。val($(this).data('icon'));

//设置更改图标套接字
var socket = io.connect('/ icon_sets / change',{query:name = my_img_name});
var siofu = new SocketIOFileUpload(socket);

siofu.listenOnInput(document.getElementById(change_icon));

//上传文件时执行某些操作
siofu.addEventListener(complete,function(){
$('。overlay')hide();
});

//显示加载窗口
socket.on('displayOverlay',displayOverlay);

//显示
socket.on('displayIconImage',function(data){
$('#iconset_render')。append('< div class = >< img src ='+ data.path +'/>< / div>');
});

socket.on('setIconsetArray',function(data){
var iconset =($('#iconset_array')。val())?JSON.parse($(' ()。()):[];

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'); //通过套接字上传文件
var config = require(__ dirname +'/config/config.json');
var easyimg = require('easyimage'); // crop - resize image
var fs = require('fs'); //文件系统访问

//创建一个socketioFileUploadServer的实例并侦听此套接字:
var uploader = new socketioFileUploadServer();
uploader.dir = config.tmpDir;
uploader.listen(socket);

//保存文件时执行某些操作:
uploader.on('saved',function(event){

console.log('Original' + type +'saved');

//调整大小并重命名具有唯一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);

//图像被上传 - 调整大小 - 裁剪,现在显示
socket.emit('display'+ ucfirst(type)+'Image',{path:'/ upload /'+ type +'/'+ newName});

//从文件系统中删除原始文件
fs.unlink(config.tmpDir + fileName,function(){
if(err)抛出错误
console.log('Original'+ type +'removed');
});

// addnal action
switch(type){
case'icon':
//发送路径生成iconset_json
socket.emit(' setIconsetArray',{iconName:newName});
break;
}

});

});

uploader.on('start',function(event){
console.log('Client start upload');
socket.emit('displayOverlay');
});

//错误处理程序:
uploader.on('error',function(event){
console.log(upload from uploader,event);
});

};

欣赏您的帮助

解决方案是



1)查询就像 GET 参数,因此将param:value替换为param = value (如果要传递多个参数,请按照通常使用URL进行操作: param = value& some_other_param = test



2)有一个更容易和更可靠(因为没有风险访问 handshaken 对象)的未定义属性,以获取<$ c中的查询参数$ c>连接处理程序:

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

编辑:



在学习完整的代码之后,我想我弄清楚是什么原因造成的。问题是你可能误解了Socket.IO命名空间的主要想法。



我想你有多个Socket.IO连接( io.connect 呼叫)在一个页面内,对吧?通常单个连接就足够了。您的错误是您在鼠标事件上调用 io.connect ,但您应该在 document.ready 上调用一次,然后只需发出 ting。



查看以下代码(客户端):

  $(document).ready(function(){
var socket = io.connect('',{query:'name = $'

// [...]

socket.on('some_event_from_server',function(data,cb){});

// [...]

$('#someButton')。click(function(){
socket.emit('markers_add',{some:数据'}); //将`markers_add`消息发送到主命名空间内的服务器
});

$('#someOtherButton')。click(function(){
socket.emit('icon_sets_add',{some:'thing'},function(response){
//服务器可能会响应此请求,请参阅下面的服务器端代码
});
});
});

服务器端代码:

  io.on('connection',function(socket){//主命名空间的连接处理程序
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',{}); //服务器向客户端发送消息

// BTW,现在应该可以:
console.log(socket.handshake.query.name);
});

如果你有一个命名空间,它应该工作。我不知道实际上是否是Socket.IO的错误或命名空间不当使用的结果,但修改代码只能使一个命名空间应该做到这一点。 所以在你的情况下,你不需要在握手时传递查询参数。实际上,如果你想让你的应用程序更安全,你必须使用查询参数。请参阅 http://wlkns.co/node-js/socket-io- authentication-tutorial-server-and-client / (对于Socket.io 0.9)



希望我的答案可以帮助您。祝你好运!


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

解决方案

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!

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

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