在 yesod-websockets 中处理断开连接
Handling disconnects in yesod-websockets
我正在尝试让 yesod-websockets 与我的基于 postgresql 的引导式 yesod 应用程序一起工作。 websocket 应该充当 postgres table 的实时更新,因此我需要维护一个包含已连接客户端列表及其用户 ID 的状态。一旦 websocket 断开连接,我如何 运行 一个函数?从更大的角度来看,这个函数应该用于从状态列表中删除websocket连接。
我目前拥有的:
type LobbyState = [(UserId, WS.Connection)]
addClient :: (UserId, WS.Connection) -> LobbyState -> LobbyState
addClient (userId, conn) state = (userId, conn) : state
chatApp :: UserId -> WebSocketsT Handler ()
chatApp userId = do
conn <- ask
-- connections is a MVar [(UserId, WS.Connection)]
connections <- lobbyConnections <$> getYesod
modifyMVar_ connections $ \s -> do
let s' = addClient (userId, conn) s
return s'
-- how to wait for disconnect and execute a function?
getGameR :: Handler TypedContent
getGameR = do
-- TODO: correct usage??
userId <- requireAuthId
webSockets $ chatApp userId
-- some more normal HTML handler code
在示例中,他们使用了以下代码段:
race_
(forever $ atomically (readTChan readChan) >>= sendTextData)
(sourceWS $$ mapM_C (\msg ->
atomically $ writeTChan writeChan $ name <> ": " <> msg))
我了解如何利用 TChan
永远发送更新,但我如何对实际断开连接事件作出反应以清理某些状态?
感谢 Chris Stryczynski 的评论,我能够通过捕获处理程序解决它。
在客户端断开连接后进行清理的示例回显服务器可能如下所示:
chatApp :: WebSocketsT Handler ()
chatApp =
( forever $ do
msg :: Text <- receiveData
sendTextData msg
)
`catch` ( \(e :: ConnectionException) -> do
let eshow = fromString $ show e
putStrLn $ eshow
-- clean up specific state here
case e of
CloseRequest code msg -> -- Handle specific close codes/msg
return ()
)
我正在尝试让 yesod-websockets 与我的基于 postgresql 的引导式 yesod 应用程序一起工作。 websocket 应该充当 postgres table 的实时更新,因此我需要维护一个包含已连接客户端列表及其用户 ID 的状态。一旦 websocket 断开连接,我如何 运行 一个函数?从更大的角度来看,这个函数应该用于从状态列表中删除websocket连接。
我目前拥有的:
type LobbyState = [(UserId, WS.Connection)]
addClient :: (UserId, WS.Connection) -> LobbyState -> LobbyState
addClient (userId, conn) state = (userId, conn) : state
chatApp :: UserId -> WebSocketsT Handler ()
chatApp userId = do
conn <- ask
-- connections is a MVar [(UserId, WS.Connection)]
connections <- lobbyConnections <$> getYesod
modifyMVar_ connections $ \s -> do
let s' = addClient (userId, conn) s
return s'
-- how to wait for disconnect and execute a function?
getGameR :: Handler TypedContent
getGameR = do
-- TODO: correct usage??
userId <- requireAuthId
webSockets $ chatApp userId
-- some more normal HTML handler code
在示例中,他们使用了以下代码段:
race_
(forever $ atomically (readTChan readChan) >>= sendTextData)
(sourceWS $$ mapM_C (\msg ->
atomically $ writeTChan writeChan $ name <> ": " <> msg))
我了解如何利用 TChan
永远发送更新,但我如何对实际断开连接事件作出反应以清理某些状态?
感谢 Chris Stryczynski 的评论,我能够通过捕获处理程序解决它。
在客户端断开连接后进行清理的示例回显服务器可能如下所示:
chatApp :: WebSocketsT Handler ()
chatApp =
( forever $ do
msg :: Text <- receiveData
sendTextData msg
)
`catch` ( \(e :: ConnectionException) -> do
let eshow = fromString $ show e
putStrLn $ eshow
-- clean up specific state here
case e of
CloseRequest code msg -> -- Handle specific close codes/msg
return ()
)