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:
parent
e79198aacb
commit
9fd03c65f9
5 changed files with 50 additions and 2 deletions
|
@ -21,9 +21,11 @@ import Git
|
||||||
import Yesod
|
import Yesod
|
||||||
import Yesod.Static
|
import Yesod.Static
|
||||||
import Text.Hamlet
|
import Text.Hamlet
|
||||||
|
import Text.Julius
|
||||||
import Network.Socket (PortNumber)
|
import Network.Socket (PortNumber)
|
||||||
import Text.Blaze.Renderer.String
|
import Text.Blaze.Renderer.String
|
||||||
import Data.Text
|
import Data.Text
|
||||||
|
import Data.Time.Clock
|
||||||
|
|
||||||
thisThread :: String
|
thisThread :: String
|
||||||
thisThread = "WebApp"
|
thisThread = "WebApp"
|
||||||
|
@ -39,6 +41,7 @@ staticFiles "static"
|
||||||
|
|
||||||
mkYesod "WebApp" [parseRoutes|
|
mkYesod "WebApp" [parseRoutes|
|
||||||
/ HomeR GET
|
/ HomeR GET
|
||||||
|
/poll PollR GET
|
||||||
/config ConfigR GET
|
/config ConfigR GET
|
||||||
/static StaticR Static getStatic
|
/static StaticR Static getStatic
|
||||||
|]
|
|]
|
||||||
|
@ -61,10 +64,25 @@ instance Yesod WebApp where
|
||||||
excludeStatic (p:_) = p /= "static"
|
excludeStatic (p:_) = p /= "static"
|
||||||
|
|
||||||
makeSessionBackend = webAppSessionBackend
|
makeSessionBackend = webAppSessionBackend
|
||||||
|
jsLoader _ = BottomOfHeadBlocking
|
||||||
|
|
||||||
getHomeR :: Handler RepHtml
|
getHomeR :: Handler RepHtml
|
||||||
getHomeR = defaultLayout $ do
|
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 :: Handler RepHtml
|
||||||
getConfigR = defaultLayout $ do
|
getConfigR = defaultLayout $ do
|
||||||
|
|
|
@ -16,3 +16,7 @@ template f = "templates" </> f
|
||||||
{- A hamlet template file. -}
|
{- A hamlet template file. -}
|
||||||
hamletTemplate :: FilePath -> FilePath
|
hamletTemplate :: FilePath -> FilePath
|
||||||
hamletTemplate f = template f ++ ".hamlet"
|
hamletTemplate f = template f ++ ".hamlet"
|
||||||
|
|
||||||
|
{- A julius template file. -}
|
||||||
|
juliusTemplate :: FilePath -> FilePath
|
||||||
|
juliusTemplate f = template f ++ ".julius"
|
||||||
|
|
|
@ -3,7 +3,6 @@ $doctype 5
|
||||||
<head>
|
<head>
|
||||||
<title>#{baseTitle webapp} #{pageTitle page}
|
<title>#{baseTitle webapp} #{pageTitle page}
|
||||||
<link rel="icon" href=@{StaticR favicon_ico} type="image/x-icon">
|
<link rel="icon" href=@{StaticR favicon_ico} type="image/x-icon">
|
||||||
|
|
||||||
^{pageHead page}
|
^{pageHead page}
|
||||||
<body>
|
<body>
|
||||||
$maybe msg <- mmsg
|
$maybe msg <- mmsg
|
||||||
|
|
25
templates/longpolling.julius
Normal file
25
templates/longpolling.julius
Normal 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
2
templates/poll.hamlet
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<div id="poll">
|
||||||
|
polled at #{time}
|
Loading…
Add table
Add a link
Reference in a new issue