yesod-websockets (empty) → 0.1.0.0
raw patch · 4 files changed
+176/−0 lines, 4 filesdep +asyncdep +basedep +conduitsetup-changed
Dependencies added: async, base, conduit, monad-control, transformers, wai-websockets, websockets, yesod-core
Files
- LICENSE +20/−0
- Setup.hs +2/−0
- Yesod/WebSockets.hs +124/−0
- yesod-websockets.cabal +30/−0
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2014 Michael Snoyman, http://www.yesodweb.com/++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be+included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Yesod/WebSockets.hs view
@@ -0,0 +1,124 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-}+module Yesod.WebSockets+ ( -- * Core API+ WebSocketsT+ , webSockets+ , receiveData+ , sendTextData+ , sendBinaryData+ -- * Conduit API+ , sourceWS+ , sinkWSText+ , sinkWSBinary+ -- * Async helpers+ , race+ , race_+ , concurrently+ , concurrently_+ ) where++import qualified Control.Concurrent.Async as A+import Control.Monad (forever, void, when)+import Control.Monad.IO.Class (MonadIO (liftIO))+import Control.Monad.Trans.Control (control)+import Control.Monad.Trans.Control (MonadBaseControl (liftBaseWith, restoreM))+import Control.Monad.Trans.Reader (ReaderT (ReaderT, runReaderT))+import qualified Data.Conduit as C+import qualified Data.Conduit.List as CL+import qualified Network.Wai.Handler.WebSockets as WaiWS+import qualified Network.WebSockets as WS+import qualified Yesod.Core as Y++-- | A transformer for a WebSockets handler.+--+-- Since 0.1.0+type WebSocketsT = ReaderT WS.Connection++-- | Attempt to run a WebSockets handler. This function first checks if the+-- client initiated a WebSockets connection and, if so, runs the provided+-- application, short-circuiting the rest of your handler. If the client did+-- not request a WebSockets connection, the rest of your handler will be called+-- instead.+--+-- Since 0.1.0+webSockets :: (Y.MonadBaseControl IO m, Y.MonadHandler m) => WebSocketsT m () -> m ()+webSockets inner = do+ req <- Y.waiRequest+ when (WaiWS.isWebSocketsReq req) $+ Y.sendRawResponse $ \src sink -> control $ \runInIO -> WaiWS.runWebSockets+ WS.defaultConnectionOptions+ (WaiWS.getRequestHead req)+ (\pconn -> do+ conn <- WS.acceptRequest pconn+ runInIO $ runReaderT inner conn)+ src+ sink++-- | Receive a piece of data from the client.+--+-- Since 0.1.0+receiveData :: (MonadIO m, WS.WebSocketsData a) => WebSocketsT m a+receiveData = ReaderT $ liftIO . WS.receiveData++-- | Send a textual messsage to the client.+--+-- Since 0.1.0+sendTextData :: (MonadIO m, WS.WebSocketsData a) => a -> WebSocketsT m ()+sendTextData x = ReaderT $ liftIO . flip WS.sendTextData x++-- | Send a binary messsage to the client.+--+-- Since 0.1.0+sendBinaryData :: (MonadIO m, WS.WebSocketsData a) => a -> WebSocketsT m ()+sendBinaryData x = ReaderT $ liftIO . flip WS.sendBinaryData x++-- | A @Source@ of WebSockets data from the user.+--+-- Since 0.1.0+sourceWS :: (MonadIO m, WS.WebSocketsData a) => C.Producer (WebSocketsT m) a+sourceWS = forever $ Y.lift receiveData >>= C.yield++-- | A @Sink@ for sending textual data to the user.+--+-- Since 0.1.0+sinkWSText :: (MonadIO m, WS.WebSocketsData a) => C.Consumer a (WebSocketsT m) ()+sinkWSText = CL.mapM_ sendTextData++-- | A @Sink@ for sending binary data to the user.+--+-- Since 0.1.0+sinkWSBinary :: (MonadIO m, WS.WebSocketsData a) => C.Consumer a (WebSocketsT m) ()+sinkWSBinary = CL.mapM_ sendBinaryData++-- | Generalized version of 'A.race'.+--+-- Since 0.1.0+race :: MonadBaseControl IO m => m a -> m b -> m (Either a b)+race x y = liftBaseWith (\run -> A.race (run x) (run y))+ >>= either (fmap Left . restoreM) (fmap Right . restoreM)++-- | Generalized version of 'A.race_'.+--+-- Since 0.1.0+race_ :: MonadBaseControl IO m => m a -> m b -> m ()+race_ x y = void $ race x y++-- | Generalized version of 'A.concurrently'. Note that if your underlying+-- monad has some kind of mutable state, the state from the second action will+-- overwrite the state from the first.+--+-- Since 0.1.0+concurrently :: MonadBaseControl IO m => m a -> m b -> m (a, b)+concurrently x y = do+ (resX, resY) <- liftBaseWith $ \run -> A.concurrently (run x) (run y)+ x' <- restoreM resX+ y' <- restoreM resY+ return (x', y')++-- | Run two actions concurrently (like 'A.concurrently'), but discard their+-- results and any modified monadic state.+--+-- Since 0.1.0+concurrently_ :: MonadBaseControl IO m => m a -> m b -> m ()+concurrently_ x y = void $ liftBaseWith $ \run -> A.concurrently (run x) (run y)
+ yesod-websockets.cabal view
@@ -0,0 +1,30 @@+-- Initial yesod-websockets.cabal generated by cabal init. For further +-- documentation, see http://haskell.org/cabal/users-guide/++name: yesod-websockets+version: 0.1.0.0+synopsis: WebSockets support for Yesod+description: WebSockets support for Yesod+homepage: https://github.com/yesodweb/yesod+license: MIT+license-file: LICENSE+author: Michael Snoyman+maintainer: michael@snoyman.com+category: Web+build-type: Simple+cabal-version: >=1.8++library+ exposed-modules: Yesod.WebSockets+ build-depends: base >= 4.5 && < 5+ , wai-websockets >= 2.1+ , websockets >= 0.8+ , transformers >= 0.2+ , yesod-core >= 1.2.7+ , monad-control >= 0.3+ , conduit >= 1.0.15.1+ , async >= 2.0.1.5++source-repository head+ type: git+ location: https://github.com/yesodweb/yesod