Created
April 6, 2012 03:04
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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