running custom functions with node and socket.io

So I would like to be able to run custom function through socket.io using node My basic idea is fairly simple, I just can't get it to work. Generally speaking you would write something similar to this to run a function on incoming message...

//server
socket.on('incomingMessage', function(data) {
    console.log(data);
    io.sockets.emit('newMessage', {id: data.id, from: data.name, message: data.message});
});
//client
socket.on('newMessage', function(data) {
    $('#messages').html($('#messages').html() + data.message);
    $('#from').html($('#from').html() + data.from);
});

but what I would like to do is allow that to be much more dynamic and actually pass the function I want to run in the message itself, so something like this...

//server
socket.on('customFunction', function(data) {
    console.log(data);
    io.sockets.emit('runFunction', data);
})

//client
socket.on('runFunction', function(data) {
    for(var index in data) {
        args.push(data[index]);
    }
    data.fn.apply(this, args);
});

but when I call this from a client using something like...

socket.emit('customFunction', {id: sessionId, name: user.name, callBack: function() { alert('it worked');
    }
});

on the server the only thing it logs is the session id and the name, the callBack(regardless of the name, I have tried func, run, cb, callBack, customFunc) just disappears. so I am kind of at a loss. Anyone have any ideas? thank you in advance for the help. I am not sure why, but when calling this it only logs the session id and the name elements, the callback, or fn, or whatever else, just isn't there. Does node or socket.io remove functions from arguments when sending things off?

You are converting data to an array and then try to call a property it doesn't have anymore then applying the data to the socket.on function (this)

so try something like:

socket.on('runFunction', function(data) {
    var arg = [];
    args.push(data.id);
    args.push(data.name);
    // etc...
    data.callback.apply(this, args);
});

I don't know if i i got you right but as far as i can see you have two options.

  1. convert your function to string, you can do that with toString() or toSource() eval it on the other side (node or client). But maybe and hopefully you don't want that :) - Important is that a function in not serialized if you use JSON.stringify or any framework solution to do that.

  2. Create an index of your callable functions and use the index to identify the function on the other side.

Example:

//create a index on one side
var runtime = {
"addMessage":function(param1,param2){  alert(arguments)   },
"whatEverFunction":function(){}
 }

 socket.on("runtime",function(data){
 if(!runtime[data.fn])return alert("runtime error");
 runtime[data.fn].apply(null,data.args);
 }


//create a call on the other
socket.io.emit({fn:"addMessage",args:["paramAValue","paramBValue"]});

If this does not help you, you may want to check if the library "dnode" does what you want.

Good Luck :)