web-dev-qa-db-ja.com

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

};

あなたの助けに感謝

12
ceadreak

はいあります。

1)queryGETパラメーターに似ているため、"param:value""param=value"に置き換えます(複数のパラメーターを渡す場合は、通常のURLの場合と同様に行います:param=value&some_other_param=test

2)handshakenハンドラー内でクエリパラメーターを取得する簡単で信頼性の高い方法(connectionオブジェクトの未定義プロパティにアクセスするリスクがないため):

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

編集:

あなたの完全なコードを学んだ後、私は問題の原因を理解したと思います。問題は、おそらくSocket.IO名前空間の主な考えを誤解していることです。

1ページ内に複数の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);
});

名前空間が1つある場合は機能します。 Socket.IOのバグなのか、名前空間の不適切な使用の結果なのかは実際にはわかりませんが、コードを変更して名前空間を1つにするだけでうまくいくはずです。 したがって、あなたの場合、ハンドシェーク時にクエリパラメータを渡す必要はまったくありません。 実際、アプリのセキュリティを強化する場合は、クエリパラメーターを使用する必要があります。 http://wlkns.co/node-js/socket-io-authentication-tutorial-server-and-client/ (Socket.io 0.9の場合)を参照してください

私の答えがお役に立てば幸いです。幸運を!

33
Oleg

これが私がやったことです。

クライアント

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

サーバ

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