【发布时间】:2014-04-29 16:12:53
【问题描述】:
如果能够从 snaplet 中使用 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)
但我的目标是维护 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 monad 中采取行动,但我对 Haskell 的理解,尤其是 Snap 中的并发性到此结束......
【问题讨论】:
标签: haskell websocket haskell-snap-framework acid-state