Skip to content

Instantly share code, notes, and snippets.

@Shadowfiend
Created April 6, 2012 03:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Shadowfiend/2316379 to your computer and use it in GitHub Desktop.
Save Shadowfiend/2316379 to your computer and use it in GitHub Desktop.
Drop-in reloading of a client on session loss based on calling a local window.serverReload function.
package bootstrap.liftweb {
import net.liftweb.common._
import net.liftweb.http._
import js._
import LiftRules._
import net.liftweb.util.Helpers._
/**
* Provides automatic reloading of the client on session loss.
*
* Lift keeps tweaking how they do this, but this is our tried-and-true
* approach for now. It's suggested that we keep monitoring Lift changes to
* how they do things so that we can adjust if they come up with a better
* strategy. One key difference is, at last check, Lift redirects the user to
* a set location (e.g., /) configured in LiftRules, whereas we reload the
* current page.
*
* Call ReloadOnSessionLoss.setup in Boot.scala to install the handlers properly.
*/
object ReloadOnSessionLoss {
def dispatch : DispatchPF = {
case req if firstSeenCometRequest_?(req) => () => Full(responseForFirstCometRequest(req))
}
def actorsForCometRequest(req:Req) : Box[List[(LiftCometActor, Long)]] = {
req.path.wholePath match {
case prefix :: tail if prefix == LiftRules.cometPath && (tail.length != 2 || tail(1) != LiftRules.cometScriptName()) =>
Full(
req.params.toList.flatMap {
case (name, when) =>
S.session.open_!.getAsyncComponent(name).toList.map(c => (c, toLong(when)))
}
)
case _ => Empty
}
}
// Returns true if this is the first comet request seen for this client.
def firstSeenCometRequest_?(req:Req) = {
(for {
actors <- actorsForCometRequest(req)
} yield {
actors.isEmpty
}) openOr (
false
)
}
def responseForFirstCometRequest(req:Req) = {
JsCommands(List(new JE.JsRaw("lift_toWatch = {}; window.serverReload ? window.serverReload() : window.location.reload();") with JsCmd)).toResponse
}
def setup {
// It's important to do this in order to control our own session loss
// scenario.
LiftRules.redirectAjaxOnSessionLoss = false
LiftRules.dispatch.append(dispatch)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment