2023-01-27 18:34:28 +01:00
|
|
|
{-# LANGUAGE AllowAmbiguousTypes #-}
|
2023-01-27 19:53:34 +01:00
|
|
|
{-# LANGUAGE DerivingVia #-}
|
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
2023-02-19 11:41:32 +01:00
|
|
|
{-# LANGUAGE FlexibleInstances #-}
|
2023-01-28 19:08:33 +01:00
|
|
|
{-# LANGUAGE LambdaCase #-}
|
2023-01-27 18:34:28 +01:00
|
|
|
|
2023-01-15 18:26:41 +01:00
|
|
|
module WebServer (runWebServer) where
|
|
|
|
|
2023-02-19 11:41:32 +01:00
|
|
|
import BroadcastUserData
|
|
|
|
( MonadBroadcast (..),
|
|
|
|
broadCastToClientsGeneric,
|
|
|
|
)
|
2023-01-27 19:53:34 +01:00
|
|
|
import ClassyPrelude hiding (decodeUtf8)
|
2023-01-29 12:08:50 +01:00
|
|
|
import Control.Monad.Except
|
2023-01-27 19:53:34 +01:00
|
|
|
import Network.HTTP.Types
|
|
|
|
import Network.Wai
|
|
|
|
import Network.Wai.Handler.Warp (run)
|
2023-01-28 19:08:33 +01:00
|
|
|
import RoomDataHandler (roomDataHandler)
|
2023-02-19 11:41:32 +01:00
|
|
|
import State.ConnectedClientsState
|
|
|
|
( MonadConnectedClientsRead (..),
|
|
|
|
getConnctedClientsGeneric,
|
|
|
|
)
|
|
|
|
import State.RoomDataState
|
|
|
|
( MonadRoomDataStateModify (..),
|
|
|
|
MonadRoomDataStateRead (getRoomDataState),
|
2023-01-27 19:53:34 +01:00
|
|
|
)
|
2023-02-19 11:41:32 +01:00
|
|
|
import Types.AppTypes (Env (..))
|
2023-01-27 19:53:34 +01:00
|
|
|
import Types.RoomsState
|
|
|
|
( HasRoomsState (getRoomsState),
|
2023-02-19 11:41:32 +01:00
|
|
|
getRoomState,
|
2023-01-27 19:53:34 +01:00
|
|
|
roomStateDiffers,
|
|
|
|
updateRoomState,
|
|
|
|
)
|
2023-01-28 19:08:33 +01:00
|
|
|
import Types.WebEnv
|
2023-01-27 18:34:28 +01:00
|
|
|
|
2023-01-29 12:08:50 +01:00
|
|
|
newtype ExceptTApp e a = E {unExceptTApp :: IO (Either e a)}
|
|
|
|
deriving
|
|
|
|
( Functor,
|
|
|
|
Applicative,
|
|
|
|
Monad,
|
|
|
|
MonadIO,
|
|
|
|
MonadError e
|
|
|
|
)
|
|
|
|
via ExceptT e IO
|
|
|
|
|
|
|
|
newtype WebApp env a = WebApp {unWebApp :: env -> IO (Either ResponseReceived a)}
|
2023-01-27 18:34:28 +01:00
|
|
|
deriving
|
|
|
|
( Functor,
|
|
|
|
Applicative,
|
|
|
|
Monad,
|
|
|
|
MonadReader env,
|
2023-01-29 12:08:50 +01:00
|
|
|
MonadIO,
|
|
|
|
MonadError ResponseReceived
|
2023-01-27 18:34:28 +01:00
|
|
|
)
|
2023-01-29 12:08:50 +01:00
|
|
|
via ReaderT env (ExceptTApp ResponseReceived)
|
|
|
|
|
2023-02-19 11:41:32 +01:00
|
|
|
instance MonadConnectedClientsRead (WebApp WebEnv) where
|
|
|
|
getConnctedClients = getConnctedClientsGeneric
|
|
|
|
|
|
|
|
instance MonadRoomDataStateModify (WebApp WebEnv) where
|
|
|
|
setRoomDataState = updateRoomState
|
|
|
|
|
|
|
|
instance MonadRoomDataStateRead (WebApp WebEnv) where
|
|
|
|
getRoomDataState = getRoomState
|
|
|
|
|
|
|
|
instance MonadBroadcast (WebApp WebEnv) where
|
|
|
|
broadCastToClients = broadCastToClientsGeneric
|
|
|
|
|
2023-01-28 19:08:33 +01:00
|
|
|
getRequestPath ::
|
2023-01-27 18:34:28 +01:00
|
|
|
( MonadIO m,
|
|
|
|
HasWebEnv env,
|
|
|
|
MonadReader env m
|
|
|
|
) =>
|
2023-01-28 19:08:33 +01:00
|
|
|
m [Text]
|
|
|
|
getRequestPath = do
|
2023-01-27 18:34:28 +01:00
|
|
|
request <- getRequest <$> ask
|
2023-01-28 19:08:33 +01:00
|
|
|
return $ pathInfo request
|
2023-01-27 18:34:28 +01:00
|
|
|
|
|
|
|
app ::
|
|
|
|
( MonadIO m,
|
|
|
|
HasWebEnv env,
|
2023-01-27 19:53:34 +01:00
|
|
|
MonadReader env m,
|
2023-02-19 11:41:32 +01:00
|
|
|
MonadError ResponseReceived m,
|
|
|
|
MonadRoomDataStateModify m,
|
|
|
|
MonadRoomDataStateRead m,
|
|
|
|
MonadBroadcast m
|
2023-01-27 18:34:28 +01:00
|
|
|
) =>
|
|
|
|
m ResponseReceived
|
2023-01-28 19:08:33 +01:00
|
|
|
app = requestPathHandler
|
|
|
|
|
|
|
|
requestPathHandler ::
|
|
|
|
( MonadIO m,
|
|
|
|
HasWebEnv env,
|
|
|
|
MonadReader env m,
|
2023-02-19 11:41:32 +01:00
|
|
|
MonadError ResponseReceived m,
|
|
|
|
MonadRoomDataStateModify m,
|
|
|
|
MonadRoomDataStateRead m,
|
|
|
|
MonadBroadcast m
|
2023-01-28 19:08:33 +01:00
|
|
|
) =>
|
|
|
|
m ResponseReceived
|
|
|
|
requestPathHandler = do
|
|
|
|
getRequestPath >>= \case
|
|
|
|
["roomdata"] -> roomDataHandler
|
|
|
|
_ -> notFound
|
|
|
|
|
|
|
|
notFound ::
|
|
|
|
( MonadIO m,
|
|
|
|
HasWebEnv env,
|
2023-01-29 12:08:50 +01:00
|
|
|
MonadReader env m,
|
|
|
|
MonadError ResponseReceived m
|
2023-01-28 19:08:33 +01:00
|
|
|
) =>
|
|
|
|
m ResponseReceived
|
|
|
|
notFound = do
|
|
|
|
respond' <- getRespond <$> ask
|
2023-01-29 12:08:50 +01:00
|
|
|
response <-
|
|
|
|
liftIO $
|
|
|
|
respond' $
|
|
|
|
responseLBS
|
|
|
|
status404
|
|
|
|
[("Content-Type", "text/plain")]
|
|
|
|
"404 - Not Found"
|
|
|
|
throwError response
|
2023-01-27 18:34:28 +01:00
|
|
|
|
|
|
|
runWebApp ::
|
|
|
|
( MonadIO m,
|
|
|
|
MonadReader Env m
|
|
|
|
) =>
|
|
|
|
m Application
|
|
|
|
runWebApp = do
|
|
|
|
env <- ask
|
|
|
|
return
|
|
|
|
( \req res -> do
|
|
|
|
let webEnv = WebEnv {appEnv = env, request = req, respond = res}
|
2023-01-29 12:08:50 +01:00
|
|
|
eitherResult <- unWebApp app webEnv
|
|
|
|
case eitherResult of
|
|
|
|
Left result -> do
|
|
|
|
liftIO $ putStrLn "Some error occured"
|
|
|
|
return result
|
|
|
|
Right result -> do
|
|
|
|
return result
|
2023-01-27 18:34:28 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
runWebServer ::
|
|
|
|
( MonadIO m,
|
|
|
|
MonadReader Env m
|
|
|
|
) =>
|
|
|
|
m ()
|
|
|
|
runWebServer = do
|
|
|
|
putStrLn "http://localhost:8081/"
|
|
|
|
runWebApp >>= liftIO . run 8081
|
|
|
|
return ()
|