haskell - 如何在 snaplet 中使用 Network.WebSockets.Snap?

标签 haskell websocket haskell-snap-framework acid-state

如果能够使用 Network.WebSockets 那就太好了模块,但我不知道如何实际做到这一点。

使用runWebSocketsSnap :: MonadSnap m => ServerApp -> m ()来自 Network.WebSockets.Snap 的函数在我的应用程序中包含一个简单的无状态 websocket 服务器很容易:

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)

但我的目标是维护 webscket 服务器的状态(例如,已连接客户端的列表,如 http://jaspervdj.be/websockets/example.html )。或者,访问 snaplet 的酸态存储也很棒。

我的第一个想法是liftIO将 websocket 操作写入 Handler App App monad,并编写一个像这样的应用程序:

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的版本这需要上述形式的应用程序,我不知道如何修改现有的应用程序( source on hackage )。在我看来,人们需要 forkIO 的替代品在 Handler App App 中执行操作相反,我对 Haskell,尤其是 Snap 中的并发性的理解到此为止......

最佳答案

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
    ...

关于haskell - 如何在 snaplet 中使用 Network.WebSockets.Snap?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22573248/

相关文章:

haskell - 惰性评估和严格评估 Haskell

list - 使用 Haskell 的 (++) 运算符追加到列表是否会导致多个列表遍历?

haskell - 将 css 和图像添加到 snap 的 cabal 构建中?

haskell - 任何 Haskell Web 服务器都可以运行 Python CGI 应用程序吗?

Docker 失败并显示 "failed to start containerd: timeout waiting for containerd to start"

haskell - 为什么这个 unsafeCoerce 不是不安全的?

haskell - 折叠功能列表?

go - 尝试恢复 Websocket 连接

go - 通过 websocket 使用 channel

javascript - 客户端重新加载页面时如何修复服务器故障?