I'm developing a multi-user desktop application. I need to figure out a way to allow only one user to login at a time per username. Basically, John can't login to the application from PC-A and then run over to PC-B and login as well. What I had in mind was to set up a bit flag that indicated that a user has logged in and when an attempt is made from another location that it would advise the user that the current username is already logged in. This would repeat until John on PC-A either exits the system or manually logs out. The only issue is if the application crashes, no logout method is called. Suggestions?
-
1look at creating a Mutex.. it will allow for only one instance is what I would suggest.. – MethodMan Dec 27 '12 at 18:23
-
You can at least attempt to [catch app crashes](http://stackoverflow.com/a/5762806/947171). No promises that you can handle it gracefully, but at least you get a chance to fix the database. – Jon Peterson Dec 27 '12 at 18:32
-
What does the server side of your application look like? Does each client instance connect directly, but only to MySQL? Or do you have your own server that in turn connects to MySQL? – O. Jones Dec 27 '12 at 18:34
2 Answers
If you can't depend on either gracefully exiting the application or at least capturing all exceptions and handling appropriately, I think the only alternative would be to go to a session approach. Basically, as each user logs in, a new session is established and it's that session id that will be validated against for any future calls.
By doing this, you can allow the use to terminate an existing/open session when they attempt to login somewhere else. If they attempt to login from PC B and are already logged in from PC A - you simply put that in a prompt and if they elect to continue from PC B, the session on PC A is deactivated. Even if someone is actively using the app on PC A, the next service call they issue should be rejected as the session is closed.
- 773
- 5
- 18
-
I'm gonna' think of this one for a bit, sounds like it may be the route to go. Thanks for the response. – Shane LeBlanc Dec 27 '12 at 18:55
Look into the GET_LOCK() and RELEASE_LOCK() functions for MySQL.
- 8,988
- 3
- 35
- 52
-
How does that solve it? If the application crashes it won't release the lock, and you have the same problem. – Barmar Dec 27 '12 at 18:23
-
1If the application crashes, it does release the lock. In fact, the lock gets released as soon as the connection goes away. – ESG Dec 27 '12 at 18:26
-
So every client has to keep a permanent database connection open as long as it's running, rather than connecting as needed. – Barmar Dec 27 '12 at 18:29
-
I agree that this violates the [open late, close early](http://weblogs.asp.net/bleroy/archive/2005/04/03/396916.aspx) philosophy. Database connections are expensive resources. – Jon Peterson Dec 27 '12 at 18:36
-
@Bamar: The linked page states "A lock obtained with GET_LOCK() is released explicitly ... or implicitly when your session terminates (either normally or abnormally)." It does use resources, but his requirement can't be met without consuming some resource. – John B. Lambe Mar 30 '17 at 21:45
-
Alternatives: - If all workstations can access a shared directory, each session could create a file and keep it open. New sessions would try to delete the file for their user account. If it can't be deleted, that client is still running. This complicates the setup and uses a file handle. - Periodically updating a record with the last update time (using the database server's clock), workstation id and user. If the record hasn't been updated for more than the update interval, then that client is not working. This is probably less efficient than holding a lock. I prefer ESG's solution. – John B. Lambe Mar 30 '17 at 21:56