Should I define socket.on('… event outside the

2019-08-30 23:20发布

问题:

I have various clients' sockets connect to my server and I need to define an event on each of them, but based on some logic, not unconditionally. Like:

for(i= 0; i<= this.users.length; i++) {
    if (i=== actionUserOrdinal) {
        io.sockets.socket(mySocketId).on('action', function(action) {...

but doing so it gets defined multiple times for some sockets during the course of running the app. And so, it gets invoked multiple times too (by the same trigger).

And if I define it the default way,

io.sockets.on('connection', function(socket) {
    socket.on('action', function(data) {
        ...

I cannot access my main app logic's variables and such. Unless I make some things global.

One solution I thought of was to delete the event after it is triggered

for(i= 0; i<= this.users.length; i++) {
    if (i=== actionUserOrdinal) {
        thisocket = io.sockets.socket(mySocketId);
        io.sockets.socket(mySocketId).on('action', function(action) {
            delete thisocket._events.action; 

(Thanks @ArdiVaba)

But I discover this is flaky and the event still gets fired twice sometimes.

Is there some other way to define the event such that it doesn't gets define more than once, by either defining it in my main app's logic itself, or by defining it in its default scope yet I still be able to access my main app's variables without going global?

回答1:

Instead of defining different events possible for each user, listen for all events for all users and in the function verify if the user is allowed to use this event.

Use sessionSockets to store the type of user and his permissions

// checkPermission function check if user is allowed to do something
checkPermissions = function(function_name, session, callback) {
    if(!session) {
        callback(null);
        return;
    }

    if(!session.user) {
        callback(null);
        return;
    }

    // If user is superuser, he has the right to do everything
    if(!session.user.superuser) {
        callback('allowed');
        return;
    }

    // TODO Here check with user and function_name if user has the right 
    // to use this function
    // use callback('allowed') if he is allowed
    // use callback(null) if he is not allowed
}

sessionSockets.on('connection', function (err, socket, session) {
  socket.on('event', function() {
    checkPermission('event', session, function(r) {
      if(r === 'allowed') {
        // User is allowed
        // Do your thing
      } else {
        // User is not allowed
        // send error message to user ?
      }
    });
  });
});