Search code examples
javascriptmongodbsessionmeteortemporary

meteor: identify client and send data to this specific client - creating block-element on other clients


My meteor app has to be used on multiple PCs by the same user, but I have to prevent a simultanous usage of the app at the same time. The problem is, that the user will change the workplace on a high frequence, so it is not a great idea to login and logout each time the user is changing the PC. I thought of using a temporary logout / blocking screen:

Example: There are five PCs. The user has been logged in the app on all five PCs. Now he wants to work on PC 1: On all other four PCs the app will be temporarily blocked by displaying an transparent overlay. If he is going to PC 2 he can remove the overlay by typing a small PIN (which is faster then doing a complete login), then he can work on this PC.

PC 1 will be blocked at the same time.

The overlay could look like this:

<div id="overlay" class="{{tempLogout}}">
    <input type="text" id="pin">
</div>

#overlay {
    display: none;
    position: fixed;
    width: 100%;
    height: 100%;
    background-color: rgba(0,0,0,0.8);
}

#overlay.logout {
    display: block !important;
}

In my helper I would do this:

Template.anything.helper({
    tempLogout: function() {
        return (Session.get('currentClient') == clientID) ? '' : 'logout';
    }
});

Now the overlay will be shown if the Session variable is false.

My problem is how to let the different clients know on which the user is currently working. And this information has to be reactive.

So in my concept I would create a random ID for each PC (maybe there is already existing any option to identify each client??) and save this ID to an data-attribute on the body-element:

$('body').attr('data-id', Random.id());

By typing the correct PIN, this ID will be saved to the user-collection:

var clientID = $('body').attr('data-id');
Session.set('currentClient', clientID);
Users.update({ _id: Meteor.id() }, { $set: { 'currentClient': clientID } });

By setting the Session variable to the new client ID, all other clients will get blocked, as the Session variable is reactive. Here I don't know which storage I have to use: the Session or the Collection.

Maybe someone has a smarter idea to get this done. Especially I think storing the clientID in a data-attribute is a little bit... hacky?? And how do I get the client ID into the helper - because there has to be the check if the currentClient is the same, then the clientID...


Solution

  • I think your concept should work. You should use Meteor.user() so you don't have to subscribe to anything (in your example you use a generic collection Users).

    You should use a global clientID and avoid to insert it in html. Something like:

      //on client
        clientID = Random.id(); //in Meteor a variable without var is global
    
    
    Template.anything.helper({
        tempLogout: function() {
            return Meteor.user().profile.clientID == clientID ? '' : 'logout';
        }
    });
    

    When the correct pin is inserted:

       Meteor.users.update({_id: Meteor.userId()}, {$set: {'profile.clientID':clientID}});
    

    You have to use Session or a global template helper if you have more than a template which you want to enable/disable.