2014-02-08 3 views
2

Я написал счастливо сервер node.js, который использует socket.io для связи с клиентом. все это хорошо работает. socket.on («соединение» ...) обработчик получил немного большим, что заставил меня думать о альтернативном способе организовать свой код и добавить обработчик в функции генератора, как это:socket.io, добавление обработчика сообщений динамически

sessionSockets.on('connection', function (err, socket, session) { 
    control.generator.apply(socket, [session]); 
} 

в генератор принимает объект, который содержит гнездовые события и их соответствующие функции обработчика:

var config = { 
    //handler for event 'a' 
    a: function(data){ 
    console.log('a'); 
    }, 

    //handler for event 'b' 
    b: function(data){ 
    console.log('b'); 
    } 
}; 


function generator(session){ 

    //set up socket.io handlers as per config 
    for(var method in config){ 
    console.log('CONTROL: adding handler for '+method); 

    //'this' is the socket, generator is called in this way 
    this.on(method, function(data){ 
     console.log('CONTROL: received '+method); 
     config[method].apply(this, data); 
    }); 
    } 
}; 

Я надеялся, что это будет добавить обработчик событий сокета к сокету, что это вид делает, но когда какое-либо событие приходит, он всегда вызывает последнее добавленное, в данном случае всегда b-функцию.

Кто-нибудь знает, что я делаю неправильно здесь?

+0

У вас больше кода, например кода, который вы используете для запуска событий? –

ответ

3

Проблема возникает из-за того, что к этому времени запускаются триггеры обратного вызова (скажем, через несколько секунд после его привязки), цикл for закончен, а значение переменной method становится последним.

Чтобы исправить это, вы можете использовать некоторые JavaScript магии:

//set up socket.io handlers as per config 
var socket = this; 
for(var method in config){ 
    console.log('CONTROL: adding handler for '+method); 

    (function(realMethod) { 
    socket.on(realMethod, function(data){ 
     console.log('CONTROL: received '+realMethod); 
     config[realMethod].apply(this, data); 
    }); 
    })(method); //declare function and call it immediately (passing the current method) 
} 

Это «магия» трудно понять, когда вы впервые видите его, но когда вы его получите, то все становится ясно :)

+0

Вау, спасибо за этот быстрый и рабочий ответ! (за исключением небольшой опечатки, вторая последняя строка должна иметь} вместо] :) –

+0

@ user3287210 да, вы правы. исправлено! – Curious

Смежные вопросы