Shutdown clients from Application Server

Questions and Answers on installation, deployment, management, locking, tranasactions of Servoy Application Server

Shutdown clients from Application Server

Postby studiomiazzo » Tue Aug 23, 2016 11:10 am

Hi everybodies,
as our application is rapidly growing, there is a lot of clients attached to Servoy application server.
As the experience tell us, users usually don't logoff but try to reconnect from another browser instance or tab (please note that we are running version 7.4.3 so we still have problems on opening a new tab from the same browser instance if already connected to the server, see https://forum.servoy.com/viewtopic.php?f=5&t=20896); this is resulting in many duplicated client.

Is it possible configuring the application server to automatically shutdown client after a user defined idle period?
Or also to shutdown a previous connected client if it tries to reconnect from the same ip address?
Is there some documentation about client management for application server?

Many thanks in advance.
User avatar
studiomiazzo
 
Posts: 124
Joined: Thu Jun 16, 2011 10:48 am
Location: Novara (IT)

Re: Shutdown clients from Application Server

Postby Peter de Groot » Tue Aug 23, 2016 11:25 am

Hi,

maybe you can use the UserManager plugin in some batch process, UserManager plugin for Servoy

Regards,
Peter
User avatar
Peter de Groot
 
Posts: 215
Joined: Thu Jan 10, 2008 8:38 pm
Location: Not sure...

Re: Shutdown clients from Application Server

Postby lwjwillemsen » Tue Aug 23, 2016 1:08 pm

Is it possible configuring the application server to automatically shutdown client after a user defined idle period?


Yes, that is possible in Servoy, check docu / wiki.

Regards,
Lambert Willemsen
Vision Development BV
lwjwillemsen
 
Posts: 680
Joined: Sat Mar 14, 2009 5:39 pm
Location: The Netherlands

Re: Shutdown clients from Application Server

Postby studiomiazzo » Tue Aug 23, 2016 2:37 pm

First of all, thank you for your replies!

Peter de Groot wrote:Hi,

maybe you can use the UserManager plugin in some batch process, UserManager plugin for Servoy

Regards,
Peter


Peter, I had a look and it seems interesting to me... did you ever test it? Do you think base version has enough features?

lwjwillemsen wrote:
Is it possible configuring the application server to automatically shutdown client after a user defined idle period?


Yes, that is possible in Servoy, check docu / wiki.

Regards,


lwjwillemsen, I really can't find anything about it... if you know where to navigate could you give me the link please? I'll appreciate it so much!!!
User avatar
studiomiazzo
 
Posts: 124
Joined: Thu Jun 16, 2011 10:48 am
Location: Novara (IT)

Re: Shutdown clients from Application Server

Postby sbutler » Tue Aug 23, 2016 3:22 pm

Timeout Configuration: http://www.servoyguy.com/knowledge_base ... web_client

Some techniques I've used in the past...

1. Simple exit on timeout (Option #1)
- Add a global date/time in your solution. Hook it into some basic functions, like when the user switches screens, and set it to current time.
onSolutionOpen, set that global to current time. Also make a call to the scheduler plugin to run every 10 minutes or so, which checks that global. If the difference between the global date/time and current time is > than your timeout time you want (say 15 minutes), then do application.exit(), or whatever you want to exit the app.

2. Simple exit on timeout (Option #2)
Use the UserManager plugin. It has a call you can run onSolutionOpen which should essentially do the same as option #1, but using Servoy's built in idle time. I believe its:
Code: Select all
plugins.UserManager.Client().maxIdleTime = X


3. Sessions based on licensing.
In your tenant table (or whatever groups users of the same company), add a column for number of licenses. Then check the number of concurrent users under that tenant and enforce the number of concurrent sessions allowed for that company. This would happen onSolutionOpen.

Code: Select all
application.addClientInfo('License " + tenantId);
var currentLicenseForTenant = application.getClientCountForInfo('License " + tenantId)
if(currentLicenseForTenant > amountLicensedForThisTenant){
   //show then a dialog that they have too many sessions open, then exit
}


4. Only allow 1 session per username.
You can keep track of the session for each user. When the username logs in, kill off their other session. So a user can only be logged in once, and old sessions die upon new session logging in.
In your user table, add a client_id. Upon logging in add some code that checks if that client_id still has a session, and if so, kill it. Then set the client_id to our new session. Something like:
Code: Select all
var oldClient = plugins.UserManager.getClientByUID(userRecord.client_id)
if(oldClient && oldClient.alive){
   oldClient.shutdown()
}
userRecord.client_id = plugins.UserManager.Client().clientId
databaseManager.saveData(userRecord)



Sometimes its appropriate to use multiple of these. For example, using #2, #3, and #4 together can be effective. It would only allow 1 session per username, kill off idle sessions, and limit the number of sessions per tenant/company to comply with your licensing model.

Lastly, make sure you've configured our timeout url and redirect stuff for the WebClient: https://wiki.servoy.com/display/public/ ... t+Settings
Otherwise they exit and can end up on the login page, which still uses a session. So you can configure what happens when the session times out.
Scott Butler
iTech Professionals, Inc.
SAN Partner

Servoy Consulting & Development
Servoy University- Training Videos
Servoy Components- Plugins, Beans, and Web Components
Servoy Guy- Tips & Resources
ServoyForge- Open Source Components
User avatar
sbutler
Servoy Expert
 
Posts: 759
Joined: Sun Jan 08, 2006 7:15 am
Location: Cincinnati, OH

Re: Shutdown clients from Application Server

Postby studiomiazzo » Tue Aug 23, 2016 5:34 pm

Thanks a lot, Scott!
I will try using the UserManager plugin.
I don't think that the timeout param in the configuration could be the right solution for me.
It has been always a bit weird to me... even if the param is currently set to the default value of 30 minutes I still have connected clients idle since hours
(and with no transactions alive...)
User avatar
studiomiazzo
 
Posts: 124
Joined: Thu Jun 16, 2011 10:48 am
Location: Novara (IT)

Re: Shutdown clients from Application Server

Postby marco.rossi » Wed Aug 24, 2016 10:59 am

Hi,

I've already used the UserManager plugin in the past to do something similar (but using headless client instead smart/web-client).
Pay attention to the client UID if you try the point 4: be sure that you are closing the right client and to get the right UID.
Marco Rossi
Senior Analyst Developer
Freelance Consultant

IT Manager @Mantho
Webmaster @Sitoliquido
marco.rossi
 
Posts: 110
Joined: Sun Apr 12, 2015 9:33 pm

Re: Shutdown clients from Application Server

Postby sovanm » Fri Aug 26, 2016 10:40 am

Hi,

studiomiazzo wrote:Is it possible configuring the application server to automatically shutdown client after a user defined idle period?


I have written a method using UserManager plugin that will check the idle timing of all connected users and if that exceed a given period of time shut them off the system. You can add a cron job every hour to check if users are idling for more than specified time limit.

Code: Select all
// Adding the method to check and remove idle users every hour
      plugins.scheduler.removeJob('remove_idle_users');
      plugins.scheduler.addCronJob('remove_idle_users', '0 0 * * * ?' , scopes.serverUtils.removeIdleUsers , dateNow);


Remove Idle users :

Code: Select all
function removeIdleUsers(){
   
   // Define the idle time limit
   var idleTImeLimit = 90;
   
   var now = new Date().getTime();    // Store the seconds when this method is triggered
   var clients = plugins.UserManager.getWebClients();     // Get all the web clients   

   // If any client present, then for each client check the idle time
   if(clients){
      
      clients.forEach(function (element, index, array) {
      
         var idleTime = clients[index].idle.getTime();      // Get the idle time
         
         // If the time difference is more than 90 min, shutdown the client
         if(((now - idleTime)/1000)/60 > idleTImeLimit){
            
            // Skipping the shutdown process for wall monitor
            if(clients[index].userName != 'skippedUser'){
               
               application.output("Client Removed from list :" + clients[index].userName +" at " + new Date() +
                  "idling since : " + clients[index].idle , LOGGINGLEVEL.INFO);
               
               clients[index].shutdown();
            } else {
               
               application.output('Skipped for skipped user :' + clients[index].userName, LOGGINGLEVEL.INFO);
            }
         }
      });
   }
}
sovanm
 
Posts: 99
Joined: Fri Oct 28, 2011 1:55 pm
Location: Bhubaneswar, India

Re: Shutdown clients from Application Server

Postby Bernd.N » Sun Aug 28, 2016 10:55 pm

Additionally, you could also check if the user logs out as you intend it, and if not put up an annoying message on his next login
- an educational measure, so to say.

That can be easily done by a flag in the user's record that gets cleared only on correct logout.
Online banking software is doing this a lot.
Bernd Korthaus
LinkedIn
Servoy 7.4.9 SC postgreSQL 9.4.11 Windows 10 Pro
User avatar
Bernd.N
 
Posts: 544
Joined: Mon Oct 21, 2013 5:57 pm
Location: Langenhorn, North Friesland, Germany

Re: Shutdown clients from Application Server

Postby patrick » Fri Sep 09, 2016 9:37 am

sovanm wrote:I have written a method using UserManager plugin that will check the idle timing of all connected users and if that exceed a given period of time shut them off the system.


Not sure why that was needed. It's essentially what the plugin does for you automatically. You can set idle times for different deployment types (smart / web) or per user (see Scott's Option #2).
Patrick Ruhsert
Servoy DACH
patrick
 
Posts: 3703
Joined: Wed Jun 11, 2003 10:33 am
Location: Munich, Germany

Re: Shutdown clients from Application Server

Postby joe26 » Wed Sep 21, 2016 6:44 pm

We are using 'plugins.UserManager.getClientByUID(clientId).shutdown()' to force clients to close down.
A list of active clients are shown and each may be selected for termination.
The client is shown as inactive, finally falling off of the active client list after 3 minutes. The client never goes away.
After the timeout and any UI interaction, the client pops up a dialog "Reconnect Failed: Old transaction or locks found, need to restart the solution.", followed by a solution selection for re-opening a client session, instead of closing the current solution.

This worked in the past, but a Java update snuck in, and seems to have hosed it.

We are running Servoy 7.1, with Java 8, Update 91.
The problem is seen directly executing it from the server or from another computer, so it is not the firewall or network settings, although those have been checked as well.

There was a problem that 7.1 worked around using Java 7: (logged error message below)

Java 7u21 broke server ability to shutdown smart clients
viewtopic.php?f=6&t=20091&p=108148&hilit=error+flushing+message+buffer+to+client#p108148

They are shut down by the server, but do not close and no other client communications seems to work either through this plugin.
So the client doesn't receive the shutdown message. The registration is complete and the server returns the requested information on the clients.

Is this the same problem as Java 1.7 and Pre-Servoy 7.x, or is this a different issue?

Thanks!
Joe

The Servoy Server error message is
com.servoy.j2db.dataprocessing.Zb Error flushing message buffer to client

This is the trace stack shown in the log:

java.lang.NullPointerException
at sun.awt.SunToolkit.getSystemEventQueueImplPP(Unknown Source)
at sun.awt.SunToolkit.getSystemEventQueueImplPP(Unknown Source)
at sun.awt.SunToolkit.getSystemEventQueueImpl(Unknown Source)
at java.awt.Toolkit.getEventQueue(Unknown Source)
at java.awt.EventQueue.invokeLater(Unknown Source)
at javax.swing.SwingUtilities.invokeLater(Unknown Source)
at com.servoy.j2db.smart.J2DBClient.invokeLater(J2DBClient.java:4063)
at com.servoy.j2db.ClientState.invokeLater(ClientState.java:1705)
at com.servoy.j2db.ClientStub.shutDown(ClientStub.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at com.sun.proxy.$Proxy18.shutDown(Unknown Source)
at com.servoy.j2db.dataprocessing.ClientProxy.Zc(ClientProxy.java:168)
at com.servoy.j2db.dataprocessing.Zo.run(Zo.java:20)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
joe26
 
Posts: 172
Joined: Wed Jun 19, 2013 10:30 pm

Re: Shutdown clients from Application Server

Postby sbutler » Wed Sep 21, 2016 9:50 pm

A possible work-around would be to close it yourself, instead of waiting for Servoy to terminate it.
I believe there is a function call in the UserManager plugin to make the client run a method, called "executeMethod". You could create a global method named "shutdownClient" which does: application.exit()

So instead of calling plugins.UserManager.getClientByUID(clientId).shutdown(), you could call plugins.UserManager.getClientByUID(clientId).executeMethod(globals.shutdownClient, null). It would close the client client-side, then the session would be removed from the server.
Scott Butler
iTech Professionals, Inc.
SAN Partner

Servoy Consulting & Development
Servoy University- Training Videos
Servoy Components- Plugins, Beans, and Web Components
Servoy Guy- Tips & Resources
ServoyForge- Open Source Components
User avatar
sbutler
Servoy Expert
 
Posts: 759
Joined: Sun Jan 08, 2006 7:15 am
Location: Cincinnati, OH

Re: Shutdown clients from Application Server

Postby joe26 » Wed Sep 21, 2016 11:52 pm

The UserManager messages aren't getting to the client apparently.
I've attempted executeMethod, sendMessage as well, without success.

downloaded the Java 6 package (jre-6u45-windows-x64) which permitted me to properly shutdown the selected client,
but got the error (below) in the Java console log on solution start. So it looks like it is definitely the issue with 7.1 and Java 6.

java.lang.UnsupportedClassVersionError: com/sun/javafx/runtime/VersionInfo : Unsupported major.minor version 52.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.sun.deploy.config.JfxRuntime.runtimeForPath(Unknown Source)
at com.sun.deploy.config.JREInfo.<init>(Unknown Source)
at com.sun.deploy.config.JREInfo.setInstalledJREList(Unknown Source)
at com.sun.deploy.config.ClientConfig.storeInstalledJREs(Unknown Source)
at com.sun.javaws.Main.launchApp(Unknown Source)
at com.sun.javaws.Main.continueInSecureThread(Unknown Source)
at com.sun.javaws.Main.access$000(Unknown Source)
at com.sun.javaws.Main$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
joe26
 
Posts: 172
Joined: Wed Jun 19, 2013 10:30 pm


Return to Servoy Server

Who is online

Users browsing this forum: No registered users and 4 guests