Haskell 如何在snaplet中使用Network.WebSockets.Snap?
如果能够从snaplet内部使用Haskell 如何在snaplet中使用Network.WebSockets.Snap?,haskell,websocket,haskell-snap-framework,acid-state,Haskell,Websocket,Haskell Snap Framework,Acid State,如果能够从snaplet内部使用Network.WebSockets模块就好了,但我不知道如何实际做到这一点 使用Network.WebSockets.Snap中的runWebSocketsSnap::MonadSnap m=>ServerApp->m()函数,很容易在我的应用程序中包含一个简单的无状态websocket服务器: routes :: [(ByteString, Handler App App ())] routes = [ ("/ws", runWebSocketsSnap ws
Network.WebSockets
模块就好了,但我不知道如何实际做到这一点
使用Network.WebSockets.Snap
中的runWebSocketsSnap::MonadSnap m=>ServerApp->m()
函数,很容易在我的应用程序中包含一个简单的无状态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)
但是没有任何版本的
runWebSocketsSnap
采用上述形式的应用程序,我也不知道如何修改现有的应用程序()。在我看来,需要一个替代forkIO
的方法,在Handler-App-App
monad中执行操作,但我对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
...
routes=[(“/ws”,webSocketsDriver)]
webSocketsDriver::Handler应用程序应用程序()
webSocketsDriver=do
appState PendingConnection->IO()
wsApp app pending=do
...
起初,这对我来说似乎没有什么意义。但是,如果需要的话,我想您可以在管理状态的应用程序中使用TVAR、MVAR或IORefs。我同意@boyd stephen smith jr,这就解决了我的问题。特别是,我可以做一些事情,比如acidState处理程序monad本质上是有状态的,因为它使App(或b和v)对您可用,而无需显式地传递它。另外,如果您想让它更简单,您可以内联定义wsApp函数(在get
行之后,dolet wsApp=…
),然后不必传入任何内容。
routes = [ ("/ws", webSocketsDriver) ]
webSocketsDriver :: Handler App App ()
webSocketsDriver = do
appState <- get
runWebSocketsSnap (wsApp appState)
wsApp :: App -> PendingConnection -> IO ()
wsApp app pending = do
...