webapp now does long polling

The webapp is now a constantly updating clock! I accomplished this amazing
feat using "long polling", with some jquery and a little custom java
script.

There are more modern techniques, but this one works everywhere.
This commit is contained in:
Joey Hess 2012-07-26 17:56:24 -04:00
parent e79198aacb
commit 9fd03c65f9
5 changed files with 50 additions and 2 deletions

View file

@ -21,9 +21,11 @@ import Git
import Yesod
import Yesod.Static
import Text.Hamlet
import Text.Julius
import Network.Socket (PortNumber)
import Text.Blaze.Renderer.String
import Data.Text
import Data.Time.Clock
thisThread :: String
thisThread = "WebApp"
@ -39,6 +41,7 @@ staticFiles "static"
mkYesod "WebApp" [parseRoutes|
/ HomeR GET
/poll PollR GET
/config ConfigR GET
/static StaticR Static getStatic
|]
@ -61,10 +64,25 @@ instance Yesod WebApp where
excludeStatic (p:_) = p /= "static"
makeSessionBackend = webAppSessionBackend
jsLoader _ = BottomOfHeadBlocking
getHomeR :: Handler RepHtml
getHomeR = defaultLayout $ do
[whamlet|Hello, World<p><a href="@{ConfigR}">config|]
[whamlet|<div id="poll">Starting ...|]
addScriptRemote "http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"
toWidgetBody $(juliusFile $ juliusTemplate "longpolling")
[whamlet|<p><a href="@{ConfigR}">config|]
{- Called by client to poll for a new webapp status display.
-
- Should block until the status has changed, and then return a div
- containing the new status, which will be inserted into the calling page.
-}
getPollR :: Handler RepHtml
getPollR = do
webapp <- getYesod
time <- show <$> liftIO getCurrentTime
hamletToRepHtml $(hamletFile $ hamletTemplate "poll")
getConfigR :: Handler RepHtml
getConfigR = defaultLayout $ do

View file

@ -16,3 +16,7 @@ template f = "templates" </> f
{- A hamlet template file. -}
hamletTemplate :: FilePath -> FilePath
hamletTemplate f = template f ++ ".hamlet"
{- A julius template file. -}
juliusTemplate :: FilePath -> FilePath
juliusTemplate f = template f ++ ".julius"

View file

@ -3,7 +3,6 @@ $doctype 5
<head>
<title>#{baseTitle webapp} #{pageTitle page}
<link rel="icon" href=@{StaticR favicon_ico} type="image/x-icon">
^{pageHead page}
<body>
$maybe msg <- mmsg

View file

@ -0,0 +1,25 @@
// Uses long-polling to update a div with id=poll.
// The PollR route should return a new div, also with id=poll.
(function( $ ) {
$.LongPoll = (function() {
return {
send : function() {
$.ajax({
'url': '@{PollR}',
'dataType': 'html',
'success': function(data, status, jqxhr) {
$('#poll').replaceWith(data);
setTimeout($.LongPoll.send, 3000);
},
});
}
}
}());
$(document).bind('ready.app', function() {
setTimeout($.LongPoll.send, 40);
});
})( jQuery );

2
templates/poll.hamlet Normal file
View file

@ -0,0 +1,2 @@
<div id="poll">
polled at #{time}