[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...
  update();
}

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
  makeNewUpdate
  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.

Regards,

Bas



More information about the Haskell-Cafe mailing list