【问题标题】:Long polling in YesodYesod的长期投票
【发布时间】:2013-06-06 00:49:55
【问题描述】:

我可以在 Yesod 或任何其他具有类似数据库设施的 Haskell Web 框架中进行长轮询吗?

确切地说,我想延迟 HTTP 响应,直到发生有趣的事情。还应该有一个超时,在此之后,客户端将收到“没有发生”的响应,然后客户端将发出相同的请求。

为了让生活变得更加复杂,我想到的应用程序通过 HTTP/HTML5 和一个非常紧凑的 UDP 协议向 MIDP 客户端提供所有内容。来自任一协议的事件都可以在任一协议中释放响应。

TIA, 阿德里安。

【问题讨论】:

    标签: haskell long-polling yesod haskell-snap-framework happstack


    【解决方案1】:

    我无法回答更复杂的 UDP 问题的所有问题,但简短的回答是,Yesod 支持长轮询。您基本上可以执行以下操作:

    myHandler = do
        mres <- timeout timeoutInMicroseconds someAction
        case mres of
            Nothing -> return nothingHappenedResponse
            Just res -> doSomething res
    

    您可能希望使用来自提升基础包的 System.Timeout.Lifted。

    【讨论】:

    • 如果面对大量请求,这个过程会耗尽服务器上的线程吗?关注stackoverflow.com/questions/405950/…的讨论后来到这里
    • GHC 的运行时支持非常多的绿色线程。我非常怀疑线程数最终会成为资源的限制因素。
    【解决方案2】:

    迈克尔的回答达到了超时要求。对于一般客户端,您不希望让 HTTP 响应等待超过 60 秒,因为它们可能正在通过代理或类似的连接,这在大约那么长的时间后往往会变得不耐烦。如果您在一个受更严格控制的网络上,那么您可以放宽此超时。一个小的更正是timeout 的参数以微秒而不是纳秒为单位。

    对于“等待有趣的事情发生”部分,我们使用来自Control.Concurrent.STMcheck 组合子(它包含retry),因此我们的处理程序线程等待TVar

    someAction = do
        interestingStuff <- atomically $ do
            currentStuff <- readTVar theStuff
            check $ isInteresting currentStuff
            return currentStuff
        respondWith interestingStuff
    

    同时,其他线程(包括 HTTP 处理程序)正在更新 theStuff :: TVar Stuff - 每次更新都会触发 isInteresting 的新计算,如果它返回 True,则可能会响应。

    这与通过 UDP 提供相同信息兼容:只需在您的 UDP 服务器线程和 Yesod 线程之间共享 theStuff

    【讨论】:

      猜你喜欢
      • 2011-04-25
      • 2013-04-13
      • 2019-04-03
      • 1970-01-01
      • 2012-10-29
      • 2012-07-14
      • 1970-01-01
      • 2012-03-15
      • 1970-01-01
      相关资源
      最近更新 更多