8

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

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

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

TIA,阿德里安。

4

2 回答 2

7

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

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

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

于 2013-06-10T14:37:52.513 回答
4

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

对于“等待有趣的事情发生”部分,我们使用check组合Control.Concurrent.STM子(它包裹起来retry)所以我们的处理程序线程等待TVar

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

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

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

于 2014-12-15T10:00:03.727 回答