Search code examples
jsonnode.jssocket.ioanonymous-function

Sending anonymous functions through socket.io?


I want to create a client-side function that can receive and execute arbitrary commands using client-side variables. I will be sending these functions from my server by using socket.io to send a JSON object containing an anonymous function which will be my command. It looks something like the following:

//client side

socket.on('executecommand', function(data){
    var a = "foo";
    data.execute(a); //should produce "foo"
});

//server side

socket.emit('executecommand', {'execute': function(param){
    console.log(param);
}});

Yet, when I tried it out, the client side received an empty json object (data == {}), then threw an exception because data contained no method execute. What is going wrong here?


Solution

  • JSON doesn't support the inclusion of function definitions/expressions.

    What you can do instead is to define a commands object with the functions you need and just pass a commandName:

    // client-side
    
    var commands = {
        log: function (param) {
            console.log(param);
        }
    };
    
    socket.on('executecommand', function(data){
        var a = 'foo';
        commands[data.commandName](a);
    });
    
    // server-side
    
    socket.emit('executecommand', { commandName: 'log' });
    

    You can also use fn.apply() to pass arguments and check the commandName matches a command with in:

    // client-side
    var commands = { /* ... */ };
    
    socket.on('executecommand', function(data){
        if (data.commandName in commands) {
            commands[data.commandName].apply(null, data.arguments || []);
        } else {
            console.error('Unrecognized command', data.commandName);
        }
    });
    
    // server-side
    
    socket.emit('executecommand', {
        commandName: 'log',
        arguments: [ 'foo' ]
    });