Jetty で実行されている Lift アプリケーションで絶対セッションタイムアウトを実装する良い方法は何ですか?
すでにアイドル タイムアウトがありますが、ユーザーがアイドル状態でなくても、最終的にセッションをタイムアウトさせたいと考えています。
Jetty で実行されている Lift アプリケーションで絶対セッションタイムアウトを実装する良い方法は何ですか?
すでにアイドル タイムアウトがありますが、ユーザーがアイドル状態でなくても、最終的にセッションをタイムアウトさせたいと考えています。
まず第一に、アクティブなコンポーネント (comet-actor、ajax-requests など) の実行中にセッションを破棄した場合の影響に注意する必要があります。ただし、セッションが無効であることを検出すると、サイドの開始/警告ページにリダイレクトするクライアントサイド スクリプトを作成できる場合があります。LiftRules.noCometSessionCmd
そしてLiftRules.noAjaxSessionCmd
、これはあなたの友達です。
現在: Lift が提供するメカニズムを活用したいと考えていSessionMaster.sessionCheckFuncs
ます。10 秒ごとにこのメソッドが実行され、現在有効なすべてのセッションが提供されます。一度もない!セッション自体への参照を保存します。これが、lift が活用できる一意の識別子を提供する理由です。ソリューションは、トラフィックの急増時にセッションを強制終了する David Pollack のコードに基づいています。
Boot.scala に以下を追加します。
// append forced session timeout to list of checker-funcs
SessionMaster.sessionCheckFuncs = SessionMaster.sessionCheckFuncs
::: List(ForcedSessionTimeout)
そして、あなたのlibパッケージで:
import net.liftweb.common._
import net.liftweb.http.SessionInfo
import net.liftweb.util.Helpers._
object ForcedSessionTimeout extends
Function2[Map[String, SessionInfo], SessionInfo => Unit, Unit]
with Loggable {
@volatile var sessionTimeoutMillis: Long = 30 * 60 * 1000 // 30 minutes
private var firstSeen: Map[String, Long] = Map.empty
def apply(sessions: Map[String, SessionInfo], destroyer: SessionInfo => Unit): Unit = {
logger.info("Session check!")
val timeoutThreshold = millis - sessionTimeoutMillis
val newFirstSeen: Map[String, Long] = sessions.map {
case (name, si @ SessionInfo(session, agent, _, cnt, lastAccess)) =>
firstSeen.get(name) match {
case Some(firstTimeSeen) =>
if (firstTimeSeen < timeoutThreshold) {
logger.info(s" Session $name expired after forced session timeout")
destroyer(si)
}
name -> firstTimeSeen
case None =>
// add to first seen list
name -> millis
}
}
// update first seen map, this prevents a leak if we added a session to the map
// but lift already expired the session for another reason
this.firstSeen = newFirstSeen
}
}