Skip to content

Instantly share code, notes, and snippets.

@codedmart
Last active August 29, 2015 14:25
Show Gist options
  • Select an option

  • Save codedmart/036dc531cd45093810d0 to your computer and use it in GitHub Desktop.

Select an option

Save codedmart/036dc531cd45093810d0 to your computer and use it in GitHub Desktop.
Main.hs:65:17:
Couldn't match type ‘a’ with ‘ResponseReceived’
‘a’ is a rigid type variable bound by
a type expected by the context:
Int -> BS.ByteString -> Builder.Builder -> SocketM a
at Main.hs:58:17
Expected type: SocketM a
Actual type: ReaderT
(Request, Response -> IO ResponseReceived) IO ResponseReceived
In a stmt of a 'do' block:
liftIO $ res (responseBuilder st [(hContentType, ct)] builder)
In the expression:
do { (_, res) <- ask;
liftIO $ res (responseBuilder st [(hContentType, ct)] builder) }
In a case alternative:
(st : _)
-> do { (_, res) <- ask;
liftIO $ res (responseBuilder st [(hContentType, ct)] builder) }
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TypeOperators #-}
import Data.Monoid ((<>))
import Data.Aeson
import GHC.Generics
import Network.Wai
import Servant
import Network.Wai.Handler.Warp (run)
import Chat (eioServer, ServerState (..))
import qualified Control.Concurrent.STM as STM
import qualified Network.SocketIO as SocketIO
import Control.Applicative
import Data.Maybe (maybeToList)
import Control.Arrow (second)
import Data.Text (pack)
import Data.Text.Lazy.Encoding (encodeUtf8)
import Data.Text.Lazy (fromStrict)
import Data.Conduit (($$), transPipe, Source)
import Data.Conduit.Lift (runCatchC)
import Data.Conduit.Attoparsec (sinkParser)
import Data.Attoparsec (parseOnly, Parser)
import Data.Monoid (mappend)
import Control.Monad (unless, liftM)
import Control.Monad.IO.Class (liftIO, MonadIO)
import Control.Monad.Trans.Reader
import Control.Monad.Trans.Resource
import Data.ByteString.Lazy (toStrict)
import Control.Exception (throwIO)
import Control.Monad.Trans.Control (control)
import Network.HTTP.Types.Header (hContentType)
import qualified Data.ByteString as BS
import qualified Data.Attoparsec.Enumerator as Attoparsec
import qualified Data.ByteString.Builder as Builder
import qualified Network.EngineIO as EIO
import qualified Data.HashMap.Strict as HashMap
import qualified Network.Wai as WAI
import qualified Network.Wai.Handler.WebSockets as WaiWS
import qualified Network.WebSockets as WS
import Network.HTTP.Types.Status as St
import Network.HTTP.Types.URI as URI
type SocketM = ReaderT (Request, Response -> IO ResponseReceived) IO
queryToHashMap :: URI.Query -> HashMap.HashMap BS.ByteString [BS.ByteString]
queryToHashMap = HashMap.fromListWith (++) . map (second maybeToList)
servantEIOAPI :: EIO.ServerAPI SocketM
servantEIOAPI = EIO.ServerAPI
{ EIO.srvTerminateWithResponse = \code ct builder -> do
let status = filter ((==) code . St.statusCode) [St.status100..St.status511]
case status of
[] -> error "not a valid status code"
(st:_) -> do
(_, res) <- ask
liftIO $ res (WAI.responseBuilder st [(hContentType, ct)] builder)
, EIO.srvGetQueryParams = fmap (queryToHashMap . WAI.queryString . fst) ask
, EIO.srvParseRequestBody = \p -> do
(req, _) <- ask
b <- liftIO $ WAI.lazyRequestBody req
return (parseOnly p $ toStrict b)
, EIO.srvGetRequestMethod = fmap (WAI.requestMethod . fst) ask
{-, EIO.srvRunWebSocket = \app -> do-}
{-(req, _) <- ask-}
{-sendRawResponseNoConduit $ \src sink ->-}
{-liftIO $ WaiWS.runWebSockets WS.defaultConnectionOptions-}
{-(WaiWS.getRequestHead req) app src sink-}
}
data User = User
{ name :: String
, age :: Int
, email :: String
} deriving (Eq, Show, Generic)
instance ToJSON User
type UserAPI = "users" :> Get '[JSON] [User]
:<|> "socket.io" :> Raw
users :: [User]
users =
[ User "Isaac Newton" 372 "[email protected]"
, User "Albert Einstein" 136 "[email protected]"
]
userAPI :: Proxy UserAPI
userAPI = Proxy
server :: Server UserAPI
server = return users
:<|> socketIOHandler
where
socketIOHandler req respond = do
respond $ responseLBS status200 [("Content-Type", "text/html")] $ encodeUtf8 $ fromStrict "testing"
app :: Application
app = serve userAPI server
main :: IO ()
main = do
putStrLn $ "Running on " <> show 3001
run 3001 app
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment