Yesod WebSocketsT 处理程序清理

Yesod WebSocketsT handler cleanup

我目前正在 Haskell 中编写一个依赖于 Yesod 及其网络套接字实现的应用程序。

我想知道为 WebSocketT 处理程序获取和释放资源的正确方法是什么。

例如,在下面的天真案例中...

chatApp :: WebSocketsT Handler ()
chatApp = do
    let outgoingFlow = forever $ deliverOutgoingMessages
    let incomingFlow = forever $ deliverIncomingMessages
    bracket_ acquireResource
             releaseResource
             (race_ outgoingFlow incomingFlow)

... releaseResource 似乎不会在客户端突然或有意断开连接时被调用。

这就是我周末做的事情。这本质上是对 web 套接字后台 ping 进程工作方式的复制,除了当另一端不再可达时我没有吞下 ping 发送异常,而是使用它来检测断开连接。

echoApp' :: WebSocketsT Handler ()
echoApp' = do
  conn <- ask
  let acquire = putStrLn "Acquiring..."
      release = putStrLn "Releasing"
      hardWork = (threadDelay 600000000)
      ping i = do
          threadDelay (30 * 1000 * 1000)
          WS.sendPing conn (T.pack $ show i)
          ping (i + 1)

  liftIO $ bracket_ acquire release $ race_ hardWork (ping 1)

这种方法的缺点是 Web 套接字进程仍然有长达 30 秒的时间 window,但至少资源最终会以或多或少可控的方式释放。