NodeJS & Socket.IO: Fire a request event and get a response, when / where should I bind a listener?

I am currently wondering what might be the best programming practice in this case:

Let's say I have a client connected to my server. And this client asks the server to authenticate with the event auth

and its username.

socket = io();
socket.emit('auth', "John");

      

In this simple case, the server responds with an event auth_succeed

with a user ID.

io.on('connection', function(socket) {
    socket.on('auth', function(username) {
        socket.emit('auth_succeed', id);
    }
}

      

So my question is when or where should I bind a listener to an event auth_succeed

in the client? There are two ways for me:

Before emitting, which guarantees, I think the response event will always be handled correctly, but will result in some spaghetti code. Example:

socket = io();
socket.on('auth_succeed', function(id){
    //Do some post-auth stuff here
}); 
socket.emit('auth', "John");

      

Or after emitting, which results in cleaner code, but perhaps I think again, skip the event if it's fast enough. Example:

socket = io();
socket.emit('auth', "John");
socket.on('auth_succeed', function(id){
    //Do some post-auth stuff here
}); 

      

What do you think about this issue?

+3


source to share


3 answers


Since the response from the issue must be asynchronous and the client side JS is synchronous in nature, the binding socket.on('auth_succeed'

will happen before the callback from the event auth

.


The following stream appears on the client ...

// EXECUTION SCOPE BEGINS
...
// this will send a message to the server
// the message and/or response will be sent asynchronously
socket.emit('auth', 'John'); 
// so your code will continue before you get anything from the server

//which means the following binding will happen before any response to the above emit
socket.on('auth_succeed', function(id){
  //... handle message from server ...
});
...
// EXECUTION SCOPE ENDS

      

Some time after the closing scope / function is executed, the "auth_succeed" event will occur.




You might also consider unblocking event handlers ...

socket.on('auth_succeed', onAuthSucceed.bind(null, socket));
socket.emit('auth', 'john');

// ... elsewhere ...

function onAuthSucceed(socket, id) {
  // handle message from server
}

      

This will reduce noise with your binding and your signaling event, whether you want to bind or emit first.

Due to the fact that the function requires something that it needs and by using an event binding, the method in question can be in a separate file / module and more easily tested in isolation.

+4


source


The socket.io docs , in Migrate from 0.9, do a great job of authenticating sockets in 1.0.

An example for you:

You need to create authentication middleware.

Create a controller named authorization.js:

/**
 * Socket.io middleware that that authorizes clients
 * @param {object} socket
 * @param {function} next
 */
module.exports = function(socket, next) {

    // do some custom auth here
    var handshakeData = socket.request;

    // make sure the handshake data looks good with some
    // custom logic
    // if doesn't you can do this:
    // next(new Error('not authorized');
    // else just call next

    next();
}

      



In index.js, just add middleware with io.use

:

var authorizeSockets = require('./controllers/authorization');
io.use(authorizeSockets);

      

Usage has io.set

been discounted for io.use()

since socket.io 1.0.

You can then tell the client that they are successfully authorized and connected by emitting auth_suceed

in the connect event, because with the new middleware in place, the socket will fail to connect unless they are successfully authorized.

io.on('connection', function(socket){
    socket.emit('auth_succeed', yourPayloadHere);
});

      

+1


source


socket.set('authorization',function(request,callback){
// check authorization for username
// set global variable flag for valid/invalid username.
if(valid_uname){
return(null,true)
}
else{
return(null,false);
}
)};
//Now on socket.on check global variable flag.
//emit when needed.

      

0


source







All Articles