1つの方法は、タイムアウトが発生した場合にサーバーを定期的にチェックすることです。サーバーセッションのタイムアウトを更新せずにそのチェックを実行するサーブレットメソッドを作成する必要があります。そしてもちろん、これは多くのサーバーヒットをもたらします。(ただし、必ずしも悪い方法ではありません!)
しかし、おそらく私は別のソリューションを使用します。これは、クライアント側のタイマーをサーバーのタイマーとほぼ同期させようとします。
クライアント側:
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);
}
}
サーバーセッションのタイムアウトは、クライアントがサーバーとの対話を実行するたびに更新されると想定しています。たとえば、GWT-RPC呼び出し(セッションがまだタイムアウトしていない場合)。
したがって、クライアント側では、クライアントタイマーを更新して、ほぼ同期を維持します。
myService.performSomeAction(...) {
@Override
public void onSuccess(String result) {
ClientTimers.renewSessionTimer();
// remaining onSuccess handling
}
@Override
public void onFailure(Throwable caught) {
if (failedBecauseOfSessionTimeout()) {
// redirect to login
} else {
ClientTimers.renewSessionTimer();
// remaining onFailure handling...
}
}
}
すべてのインタラクションで(特にログイン直後に)renewSessionTimer()を呼び出すことを忘れないでください。
重要な注意:すべてのセキュリティチェックでは、サーバーセッションのみを使用してください。クライアントの「セッションタイマー」は、ユーザーにとって便利なものです。そのタイマーまたは任意の種類のクライアントセッションに依存するセキュリティ/承認チェックを行わないでください。