on master help sign in
Merge pull request #638 from mschristiansen/wai-extra-app

Update SSE example in wai-extra. Fixes #635

commit3836978dd46e01bd1251a8faf1c85b27219ef340 authorMichael Snoyman <michael@snoyman.com> dateTue 8 Aug 2017, 08:25 (9 years ago) parent4f5da6ba8a0c51
5 files changed+62−28
stack.yaml+3 wai-extra/README.md+14−1 wai-extra/app/Main.hs → wai-extra/example/Main.hs+21−25 wai-extra/app/index.html → wai-extra/example/index.html+3−2 wai-extra/wai-extra.cabal+21
stack.yaml+3
@@ -11,6 +11,9 @@ packages:
1111- ./wai-websockets
1212- ./wai-conduit
1313- ./tls-session-manager
14+flags:
15+ wai-extra:
16+ build-example: true
1417extra-deps:
1518- http2-1.6.0
1619- cryptonite-0.23
wai-extra/README.md+14−1
@@ -1,3 +1,16 @@
1−## wai-extra
1+# wai-extra
22
33The goal here is to provide common features without many dependencies.
4+
5+
6+## Example using Server-Sent Events ##
7+
8+There is a small example using Server-Sent Events (SSE) in the
9+`./example` directory.
10+
11+Run the commands below to start the server on http://localhost:8080
12+
13+```
14+$ stack build .
15+$ stack exec example
16+```
wai-extra/app/Main.hs → wai-extra/example/Main.hsrenamed+21−25
@@ -1,28 +1,26 @@
11{-# LANGUAGE OverloadedStrings #-}
22module Main where
33
4−import Control.Monad
4+import Blaze.ByteString.Builder.Char.Utf8 (fromString)
55import Control.Concurrent (forkIO, threadDelay)
6−import Control.Monad.Trans (liftIO)
76import Control.Concurrent.Chan
7+import Control.Monad
8+import Data.Time.Clock.POSIX (getPOSIXTime)
9+import Network.HTTP.Types (status200)
10+import Network.Wai (Application, Middleware, pathInfo, responseFile)
11+import Network.Wai.EventSource (ServerEvent(..), eventSourceAppChan, eventSourceAppIO)
812import Network.Wai.Handler.Warp (run)
13+import Network.Wai.Middleware.AddHeaders (addHeaders)
914import Network.Wai.Middleware.Gzip (gzip, def)
10−import Network.Wai
11−import Network.HTTP.Types (status200)
12−import Data.Time.Clock.POSIX
13−import Blaze.ByteString.Builder.Char.Utf8 (fromString)
14−import qualified Data.Conduit as C
1515
16−import Network.Wai.EventSource
1716
1817app :: Chan ServerEvent -> Application
19−app chan req =
18+app chan req respond =
2019 case pathInfo req of
21− [] -> return $ ResponseFile status200 [("Content-Type", "text/html")] "static/index.html" Nothing
22− ["esold"] -> eventSourceAppChan chan req
23− ["eschan"] -> eventSourceAppChan chan req
24− ["esio"] -> eventSourceAppIO eventIO req
25− ["essrc"] -> eventSourceAppSource eventSource req
20+ [] -> respond $ responseFile status200 [("Content-Type", "text/html")] "example/index.html" Nothing
21+ ["esold"] -> eventSourceAppChan chan req respond
22+ ["eschan"] -> eventSourceAppChan chan req respond
23+ ["esio"] -> eventSourceAppIO eventIO req respond
2624 _ -> error "unexpected pathInfo"
2725
2826eventChan :: Chan ServerEvent -> IO ()
@@ -39,17 +37,15 @@ eventIO = do
3937 Nothing
4038 [fromString . show $ time]
4139
42−eventSource :: C.Source (C.ResourceT IO) ServerEvent
43−eventSource = forever $ do
44− time <- liftIO $ do
45− threadDelay 1000000
46− getPOSIXTime
47− C.yield $ ServerEvent (Just $ fromString "source")
48− Nothing
49− [fromString . show $ time]
50−
40+main :: IO ()
5141main = do
5242 chan <- newChan
5343 _ <- forkIO . eventChan $ chan
54− run 8080 (gzip def $ app chan)
55−
44+ run 8080 (gzip def $ headers $ app chan)
45+ where
46+ -- headers required for SSE to work through nginx
47+ -- not required if using warp directly
48+ headers :: Middleware
49+ headers = addHeaders [ ("X-Accel-Buffering", "no")
50+ , ("Cache-Control", "no-cache")
51+ ]
wai-extra/app/index.html → wai-extra/example/index.htmlrenamed+3−2
@@ -1,8 +1,9 @@
11<!doctype html>
22<head>
3− <title>Hello</title>
3+ <title>Example</title>
4+ <link rel="icon" href="data:;base64,=">
45</head>
5−<h1>Testing</h1>
6+<h1>Testing Server-Sent Events</h1>
67
78<div id="output"></div>
89
wai-extra/wai-extra.cabal+21
@@ -81,6 +81,11 @@ extra-source-files:
8181 ChangeLog.md
8282 README.md
8383
84+flag build-example
85+ description: Build example executable.
86+ manual: True
87+ default: False
88+
8489Library
8590 Build-Depends: base >= 4.6 && < 5
8691 , bytestring >= 0.9.1.4
@@ -155,6 +160,22 @@ Library
155160 default-language: Haskell2010
156161 ghc-options: -Wall
157162
163+executable example
164+ hs-source-dirs: example
165+ main-is: Main.hs
166+ ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
167+ if flag(build-example)
168+ build-depends: base
169+ , wai-extra
170+ , warp
171+ , wai
172+ , time
173+ , http-types
174+ , blaze-builder
175+ else
176+ buildable: False
177+ default-language: Haskell2010
178+
158179test-suite spec
159180 type: exitcode-stdio-1.0
160181 hs-source-dirs: test