At CounterPath, my GWT application has an auto-logout feature.
This is to avoid the situation where an application user doesn't do anything for a while, and then edits a pile of information and clicks 'Save', only to find out their session timer has expired, meaning they just lost their work.
The auto-logout feature keeps an internal timer that matches the server's session timeout.
The internal timer is reset every time I do some server interaction.
To avoid inserting these calls all over the place in my code, I added an Async RPC facade; My application uses the facade, and the facade makes the call to the server.
The downside is that I have to maintain another copy of the RPC interface. Fortunately, that part is quite stable.
For example, I have:
- MyData - the RPC interface
- MyDataAsync - the Async version of MyData
- MyDataAsyncSession - a class that implements MyDataAsync
MyData:
public interface MyData extends RemoteService { public Data getData(); }
MyDataAsync:
public interface MyDataAsync { public void getData(AsyncCallback<Data> callback); etc... }
And, in my client code,
MyDataAsyncSession:
public class MyDataAsyncSession implements MyDataAsync { MyDataAsync realRPC = (MyDataAsync)GWT.create(MyData.class); @Override public void getData(AsyncCallback<Data> result) { resetSessionTimer(); realRPC.getData(result); } etc...
In my actual client code, I would then have:
If this was all on the server, I could probably use AOP to insert calls to resetSessionTimer() in the right places...
On to the main point of this post.
In a few places, I use popup dialogs.
This leads to a problem: If you do something that generates a popup dialog, and then let it sit there for 30 minutes, the GWT application will auto-log-out, which will hide the other panels and show the login panel. However, it won't hide the popup dialogs! They will continue to show whatever was being worked on.
At first, I was considering a popup registration system, maintaining a list of popups that are currently open. This could get messy, with some popups being auto-close, and others closed with a button or other control.
Fortunately, I found an easier way: Just search the default root panel for PopupPanel widgets, and close them!
Here is the code, which is now part of my doLogout() function:
That's a lot easier than having to maintain a list of open popups!
MyDataAsyncSession rpc = new MyDataAsyncSession(); rpc.getData(new AsyncCallback<Data>(){...});In this way, I don't have to worry about sprinkling calls to resetSessionTimer all over my code.
If this was all on the server, I could probably use AOP to insert calls to resetSessionTimer() in the right places...
On to the main point of this post.
In a few places, I use popup dialogs.
This leads to a problem: If you do something that generates a popup dialog, and then let it sit there for 30 minutes, the GWT application will auto-log-out, which will hide the other panels and show the login panel. However, it won't hide the popup dialogs! They will continue to show whatever was being worked on.
At first, I was considering a popup registration system, maintaining a list of popups that are currently open. This could get messy, with some popups being auto-close, and others closed with a button or other control.
Fortunately, I found an easier way: Just search the default root panel for PopupPanel widgets, and close them!
Here is the code, which is now part of my doLogout() function:
Code to Auto-Close Popup Panels
// Create a widget processing list, and // add the default root panel to it. ListwidgetList = new ArrayList (); widgetList.add(RootPanel.get()); while(!widgetList.isEmpty()) { // Pull the first widget from the list Widget w = widgetList.remove(0); // If it is a popup, hide it! if (w instanceof PopupPanel) { ((PopupPanel)w).hide(); } else if (w instanceof HasWidgets) { // Add any child widgets to the processing list. Iterator iter = ((HasWidgets)w).iterator(); while(iter.hasNext()) { Widget child = iter.next(); widgetList.add(child); } } }
That's a lot easier than having to maintain a list of open popups!
No comments:
Post a Comment