Session management in the gwt - java

I am working on an GWT-ext application.
In this application I managed client side session. For this I write below code:
To manage the session:
import com.google.gwt.user.client.Timer;
public class ClientTimers {
private static final Timer SESSION_MAY_HAVE_EXPIRED_TIMER = new Timer() {
#Override
public void run() {
// Warn the user, that the session may have expired.
// You could then show a login dialog, etc...
}
};
public static void renewSessionTimer() {
// First cancel the previous timer
SESSION_MAY_HAVE_EXPIRED_TIMER.cancel();
// Schedule again in 5 minutes (maybe make that configurable?)
// Actually, let's subtract 10 seconds from that, because our timer
// won't be synchronized perfectly with the server's timer.
SESSION_MAY_HAVE_EXPIRED_TIMER.schedule(5 * 60 * 1000 - 10000);
}
}
To get the user activity:
Ext.get("pagePanel").addListener("click", new EventCallback() {
#Override
public void execute(EventObject e) {
//MessageBox.alert("On Mouse Click");
});
Ext.get("pagePanel").addListener("keydown", new EventCallback() {
#Override
public void execute(EventObject e) { //
//MessageBox.alert("On Key Press Click");
}
});
This code is working fine but my issues :
This code will do log out automatically as the time out occurs.For my code I want that on click or key down it should do logout. Case is like this:If user is logged in and time to log out is 5 min.User don't do any activity on the screen than right now as per the above code it will log out automatically as the 5 min complete.
Now my requirement is that if user logged in and it doesn't do any thing for 5 mins.It should not do any logged out automatically.Instead of logging out on completion of 5 min,If user do click or key down on 6 min then it should do the log out process.
Basically the log out process as the timer exceed the specified time should be done on the user activity, not automatically.

In the Timer, increment a variable for each second.
And when user click on any button after 5 minutes or on 6th minute than check the counter variable and if the variable is greater than 6 than you can use Window.Location.reload(); to logout or reload().

I think the thing you are searchin for is:
Window.Location.reload();
Fire it every few secons with a timer, so the user always apper to be active.
(Btw I have that from Window close issues in gwt -ext )

Install a JavaScript event handler on an invisible div that covers the whole area. If it gets an event, send an AJAX request to the server.
The server can then do whatever it needs to do. On the client side, you can wait for a reply from the AJAX request and display "You have been logged out".
There is one drawback of this approach: Objects stored in the session will be kept alive for too long. So even if the user never logs out and just walks away (or his browser crashes), the session will stay alive.
After a couple of days, so many dead sessions will accumulate that your server will crash.
So the better solution is to auto logout the user as you do already and install an AJAX event handler as described above to display a message when the user returns to the browser.
This way, your server can clean up dead sessions and the user gets a message when he can read it (when he is in front of the screen).
Note that you can't differentiate between the user and the cleaning crew hitting the mouse.

Related

send data to server every minute (For check status user)

For check status user i should send some data to server every 5 minutes with retrofit2.
Of course, this information should be sent when the user is in the app
This means that when the user is out of the application, there is no need to send something to the server
What is the best way to do this?
For connection to server i use retrofit2.
One solution is to use Android's work manager to ping your server with http request. You can create initial OneTimeWorkRequest when user logins and with in each execution create a new OneTimeWorkRequest with 5 minutes delay. When user exits the app cancel all the work request.
See the Jetpack Library: https://developer.android.com/topic/libraries/architecture/workmanager
Another solution for which you need to make changes in your architecture is to use Sockets with library like SocketIO. Connect the socket from your app when user login notifying server that user is online. When socket disconnect server can mark user offline: https://socket.io/blog/native-socket-io-and-android/
One other solution is to use Firebase Realtime database for presence system. Firebase has nice example of how to do this: https://firebase.googleblog.com/2013/06/how-to-build-presence-system.html
You can write this code in service and make network call every 5 minutes using handler or RxJava;
public class YourService extends Service{
public final Handler handler = new Handler();
#Override
public void onCreate() {
makeCallEvery5Min();
}
private void makeCallEvery5Min(){
runnable = new Runnable() {
#Override
public void run() {
// execute call here
}
handler.postDelayed(runnable, delay);
}
}
}
RXJava
private void makeCallEvery5min() {
Observable.interval(0, 5, TimeUnit.MINUTES)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(v -> your_network_call() );
}
May help you below approach
If user is log in, should have user id.
Now try to check for user id of particular user in user log in session.
Note: below code should be added in web page(jsp or servlet)--.
Single User Approach:if(userId==Session.getUserId(userId)){response.refresh(5);//write code to send data to server using retrofit2.}
MultiUser Approach: multiple users log in.if(Session.getUsers()!=null){response.refresh(5);//write code to send data to server using retrofit2 }

ending JVM when the browser tab is closed in spring boot application

I have a spring-boot web application to be distributed as jar file. The code to start the application is as follows:
private static ConfigurableApplicationContext ctx;
public static void main(String[] args){
if(ctx == null) {
ctx = SpringApplication.run(MyApplication.class, args);
}
try {
openHomePage("http://localhost:8090/");
}catch(Exception e) {
logger.error("Error occured starting the application: ", e);
ctx.close();
}
}
private static void openHomePage(String url) throws IOException, URISyntaxException {
if(Desktop.isDesktopSupported()) {
URI homePage = new URI(url);
Desktop.getDesktop().browse(homePage);
}else {
Runtime runtime = Runtime.getRuntime();
runtime.exec(new String[]{"cmd", "/c","start chrome " + url});
}
}
which opens the home page in Chrome, both when I run it from Eclipse and by double clicking on the jar file.
The problem is when I start the application from the jar file and close the browser tab, the application continues to run in JVM and I have to kill it from the task manager manually which is annoying. If I don't kill the JVM and double click on the jar file again, then the application doesn't start automatically as it does the first time, and I have to manually open a new browser tab and type http://localhost:8090/ in order to use the application.
Is it possible to kill every process after user closes the browser tab so that when they click on the jar file next time they need to use the application, a fresh browser tab opens automatically?
Thanks in advance..
SOLUTION
This might not be the best solution but it works a treat.
*Step 1 - Send heartbeats from the browser
var heartBeatIntervals = null;
$( document ).ready(function() {
//this ajax call will be fired every 2 seconds as long as the browser tab stays open.
// the time intervals can of course be modified
heartBeatIntervals = setInterval(() => {
$.ajax({
type:'POST',
url: 'http://localhost:8090/MyController/checkHeartbeats'
})
}, 2*1000);
});
*Step 2 - Handle the heartbeats in the server
#Controller
#RequestMapping("/MyController")
public class MyController {
//declare an instance variable to store the number of missed heartbeats
private int missedHeartbeats = 0;
//reset the counter to 0 upon receiving the heartbeats
#PostMapping("/checkHeartbeats")
public void checkHeartbeats() {
missedHeartbeats = 0;
}
//increase the missedHeartbeats by one every 3 seconds - or whatever
#Scheduled(fixedRate = 3000)
public void schedule() {
missedHeartbeats++;
//check how many heartbeats are missed and if it reaches to a certain value
if(missedHeartbeats > 5) {
//terminate the JVM (also terminates the servlet context in Eclipse)
System.exit(0);
}
}
}
*Step - 3 Enable scheduling
In order to use any scheduling in spring-boot application you need to add #EnableScheduling annotation in your class where your main method resides.
And that's it.
There's a stop button in Eclipse. And in case it can't be used:
You can send something from javascript to your server continiously and when server haven't recieved it for 1 sec, which means the web page was closed, stop itself.
Solution 1
Use a method in any #Controller to handle heartbeat requests.
Store the most recent heartbeat time in a static field of any class, the initial value could be 0 or -1 indicating the web page has not been opened yet.
Use a #Scheduled task to retrive last heartbeat time and compare with current time. schedule the task once per 2 second or whatever. https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/scheduling.html#scheduling-annotation-support
Stop JVM if needed, maybe by System.exit(0).
Solution 2
It would be easier if you can add a Close button on webpage. being clicked, it signals the server to stop, and afterwards it closes the web page itself. https://stackoverflow.com/a/18776480/9399618

Android - Fingerprint scanner stops working after 5 attempts?

A bit of a weird issue when using the fingerprint scanner in Android 6.0 (Marshmallow) that I am stuck with and can't figure out.
I have searched all over but can only see things related to hardware defects.
The application accepts, encrypts, decrypts and validates fingerprints just fine, however it only allows 5 attempts before it for some reason stops working. (More on that below)
I have setup the application to allow the user four scan attempts before implementing a security lockout timer, however if I intentionally fail to authenticate 4 times. Then I wait to lockout period of 5 minutes and come back I can only scan my finger once, after that the fingerprint appears to stop listening until I force quit the application from Applications Manager?
It then accepts fingerprints again.
Code for authenticationFailed callback:
#Override
public void onAuthenticationFailed() {
authenticationDialog.dismiss();
cancellationSignal.cancel();
//Add one to the number of attempts taken
attemptCount += 1;
if (attemptCount < maxAttempAllowance) {
AlertDialog.Builder message = new AlertDialog.Builder(appContext);
message.setTitle("Authentication Failed");
message.setMessage("The finger you scanned is not registered in your devices settings or your device failed to identify you.");
message.setPositiveButton("Try Again", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
showAuthenticationDialog();
startAuth(manager, cryptoObject);
}
});
message.setIcon(R.drawable.cross_flat);
message.setCancelable(false);
message.show();
}
else {
AlertDialog.Builder message = new AlertDialog.Builder(appContext);
message.setTitle("Authentication Failed");
message.setMessage("You have exceeded the maximum login attempts allowed. Try again in 5 minutes.");
message.setIcon(R.drawable.cross_flat);
message.setCancelable(false);
message.show();
setSecurityBanTimer();
}
}
Even without the lockout security code the scanner still only accepts 5 prints.
I have found at that the API forces the security to have a 30 second gap between 5th and further attempts.
This means that the scanner will be unresponsive after the 5th attempt if the security of the application sets lockout at 4.
Documentation:
Device implementations with a secure lock screen SHOULD include a fingerprint sensor. If a device implementation includes a fingerprint sensor and has a corresponding API for third-party developers, it:
MUST rate limit attempts for at least 30 seconds after 5 false trials for fingerprint verification.
Find information here.

how to get user logout time when user closes the web browser without logging out from application [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have created web application that handle user login with it and update logout time when user logout from application, but when user close web browser directly or system gone shutdown with some problem, i am not able to update user logout time.
Please give any possible way to update user logout time on such circumstances.
Assuming javascript on client side as it is a webapp.
In such cases you should send a request in browser close event
window.onbeforeunload = function(event) {
//send request to server .
}
Prefer to read :want to detect browser close event?
May the following steps help you to update logout time.
1.Keep updating a timestamp variable in session for each request.
2.During session time out get the variable value (which holds when user accessed at last) and update in logout record.
This could help without depending the browser to send logout request.
try this code to implement
window.onbeforeunload = function(event) {
var isOK = confirm("Are you sure to Leave this Page?");
if(isOK)
{
// try ajax for update your table
}
}
You can create a class which implements HttpSessionListener and annotated #WebListener() like this:
#WebListener()
public class MyListener implements HttpSessionListener {
#Override
public void sessionCreated(HttpSessionEvent se) {
}
#Override
public void sessionDestroyed(HttpSessionEvent se) {
Date lougOutDate=new java.util.Date();
}
}
in sessionDestroyed method you retrieve the date of disconnection
Why don't you use a TimeOut ?
There is several solutions :
Timeout
Implement HTTP COOKIE. Check the link below
http://en.wikipedia.org/wiki/HTTP_cookie
In your specific case it should be Session Cookie
Session cookie
A user's session cookie[14] (also known as an in-memory cookie or transient cookie) for a website exists in temporary memory only while the user is reading and navigating the website. When an expiry date or validity interval is not set at cookie creation time, a session cookie is created. Web browsers normally delete session cookies when the user closes the browser.[15][16]
Do the stuff with Javascript as suggested
Hope it's help :)
You could try to write some Javascript that sends an "User logging out" message to the server. This code should be triggered using $.unload() (if you're using jQuery) or binding to the native unloadevent of the browser.
There is no way of precisely getting the logout time in such circumstances, as this might be for example caused by internet connection loss.
Some possibilities:
Send an ajax request on document unload to notify your server (as suggested by #Baadshah and #mthmulders)
Add a session timeout listener on the server to set the logout time when the session times out - this way even if the ajax doesn't get to the server you will know that the user logged out during the last few minutes (depending on the session duration)
Use the event beforeunload with jquery on your page.
The beforeunload event fires whenever the user leaves your page for any reason.
For example, it will be fired if the user submits a form, clicks a link, closes the window (or tab), or goes to a new page using the address bar, search box, or a bookmark.
You could exclude form submissions and hyperlinks (except from other frames) with the following code:
var inFormOrLink = false;
$(document).on('click','a', function() { inFormOrLink = true; });
$(document).bind('submit','form', function() { inFormOrLink = true; });
$(window).on('beforeunload',document, function(eventObject) {
var returnValue = undefined;
if (inFormOrLink == false) {
//do your action
}
});
EDIT: Answer found here: How to capture the browser window close event?

How to set a timer for activity of users?

I need to execute a specific method if user stop working in 5 hours.
Lets say user is signed in, but he does not add any record to a specific table of database for 5 hours.
Any time user adds a record to the specified table, the timer of that particular user should be reset otherwise it will keep going.
If it reaches to 5 hours , application should show a message indicating that you have not added any record for 5 hours.
To clarify please have a look at these steps
1- (1:00 PM) user1 is signed in -> timer of user1 is set
3- (1:00 PM) user2 is signed in -> timer of user2 is set
5- (1:10 PM) user1 adds something to the tableA
-> timer of user1 will be reset
6- (6:00 PM) user1 adds something to the tableA
-> timer of user1 will be reset
7- (6:00 PM) 5 hours is elapsed for user2 without adding any record to tableA
-> show the message to user2
8- (11:10 PM) 5 hours is elapsed for user1 without adding a record to TableA
-> show the message to user1
....
As shown above I do not care what they do while being signed in. I just care about adding records to that specific table. (TableA) For example user 2 is active but does not add any
record to tableA so receives the message once his timer reaches to 5 hours.
I've found the following except, but suppose it is not useful, as once I run it in user's class, it is not possible to get back to the same class and reset it.
Timer timer = new Timer();
int startingTime=10000; //millisecond 10 seconds=10000
int delayTime=1000; // millisecond 1 second
timer.schedule(new TimerTask()
{
public void run() {
System.out.println("Timer repeat statement");
}
},startingTime,delayTime);
Since you use java-ee and struts, I assume you are talking about web-app.
So use standard session management. Implement HttpSessionActivationListener to init the timer on session start, and set your session time out to 5 hours. When session expired, run you code.
You need to implement session-scope bean to check this, and reset the timer with a method called from your service layer to this bean, when a record to specific table performed.
Also you have to check timer associated with current session in your JSP to check if you need to display message.
E.g. you created TimerBean - some bean with session-related timer to check from JSP.
1.
public class SessionListener implements HttpSessionListener {
#Override
public void sessionCreated(HttpSessionEvent arg0) {
//init your timer in TimerBean and associate it with created session
}
#Override
public void sessionDestroyed(HttpSessionEvent arg0) {
//check your timer value and run you code if it's necessary
}
}
2.
#Startup //use eager initialization, or call init from login page
#Singleton // singleton session bean
public class YourDbTableSessionManager {
#Resource
private javax.ejb.SessionContext
void writeToDb {
//reset your timer in TimerBean for SessionContext
//perform write
}
}
3.
web.xml
<web-app ...>
<listener>
<listener-class>your.package.SessionListener</listener-class>
</listener>
</web-app>

Categories

Resources