[Haskell-cafe] Happstack events and web page refreshing

Bas van Dijk v.dijk.bas at gmail.com
Wed Jan 19 17:03:12 CET 2011

On 19 January 2011 15:02, Corentin Dupont <corentin.dupont at gmail.com> wrote:
> Is what you explained feasible on the user's side of happstack-server (I
> mean, if I can do it myself)?

Yes, you can do it yourself.

> If I take an empty MVar in my ServerPartTs, which are read over client's
> request,
> I think that nothing will be sent back to the browser and it will remain
> blank!

Yes, which is the intention.

Here's a short incomplete and non type-checked snapshot of an
application I'm currently developing which uses long-polling:

Somewhere on the client you have the following Javascript which uses
the JQuery library:

update = function(){
  $.ajax({url: "update", success: onUpdate});

onUpdate = function(data){
  // Update your page, possibly by making more ajax requests to the server...

Now when you call update() the client will asynchronously request the
server for updates. Each time there's an update the onUpdate function
is run which gives you a chance to update your page. onUpdate will
finally call update() again for the next iteration.

Now on the server side you need something like this:

main :: IO ()
main = do
  sessionStore  <- newSessionStore
  forkIO (updateLoop sessionStore)
  simpleHTTP conf $ msum
    [ dir  "update" (update sessionStore), ... ]

update :: SessionStore -> ServerPartT IO Response
update sessionStore = do
  mvar <- getSessionData sessionStore
  liftIO $ takeMVar mvar
  return someResponse

getSessionData will check if there's an active session and if so will
return the associated MVar. If there's no active session a new one
will be created which will have an empty MVar associated with it.

updateLoop is a loop that creates a new update and then notifies the clients:

updateLoop :: SessionStore -> IO ()
updateLoop store = forever $ do
  notifySessions store

notifySessions :: SessionStore -> IO ()
notifySessions store = do
  sessionData <- getAllSessionData store
  mapM_ (\mv -> tryPutMVar mv ()) sessionData

Note that it's not necessary to have a separate thread for creating
updates and notifying clients. You can just as well do this in one of
your request handlers.

I know the example is incomplete but I hope I got the essentials across.

> Is that to be combined with an HTTP refresh timer on the client side?

No, as Thu already explain, no HTTP refresh timer is needed.

> By sessions, you mean sessions that I create myself for every client
> connected?

Yes. However, I don't think sessions are required for long-polling. I
just used them in my example because I used them in a similar way in
an application I'm currently developing.



More information about the Haskell-Cafe mailing list