How to use Network.WebSockets.Snap in snaplet?

It would be nice to be able to use the module Network.WebSocketsfrom within the snap-in, but I cannot figure out how to actually do this.

Using the function runWebSocketsSnap :: MonadSnap m => ServerApp -> m ()from Network.WebSockets.Snap, in my application it is easy to turn on a simple server without taking into account the state without registering:

routes :: [(ByteString, Handler App App ())]
routes = [ ("/ws", runWebSocketsSnap wsApp) ]

wsApp :: PendingConnection -> IO () -- this is the ServerApp type
wsApp pending = do
    conn <- acceptRequest pending
    forever $ do
        msg <- receiveData conn
        sendTextData conn ("Echo " `mappend` msg :: Text)

But my goal is to maintain state for the web page server (for example, a list of connected clients, as in http://jaspervdj.be/websockets/example.html ). Alternatively, access to the storage of acid states of the fixative will be greater.

My first idea was to liftIOwebsocket in the monad Handler App Appand wrote an application like this:

wsApp :: PendingConnection -> Handler App App ()
wsApp pending = do
    conn <- liftIO $ acceptRequest pending
    forever $ do
        msg <- liftIO $ receiveData conn
        update (SetLastMsg msg)
        liftIO $ sendTextData conn ("Stored msg in datastore.")

runWebSocketsSnap, , , ( ). , forkIO, Handler App App , Haskell concurrency Snap ...

+4
1

runWebSocketsSnap , PendingConnection -> IO (). , . , .

routes = [ ("/ws", webSocketsDriver) ]

webSocketsDriver :: Handler App App ()
webSocketsDriver = do
    appState <- get
    runWebSocketsSnap (wsApp appState)

wsApp :: App -> PendingConnection -> IO ()
wsApp app pending = do
    ...
+3

Source: https://habr.com/ru/post/1532941/


All Articles