我可以在 Yesod 或任何其他具有类似数据库设施的 Haskell Web 框架中进行长轮询吗?
准确地说,我想延迟 HTTP 响应,直到发生有趣的事情。还应该有一个超时,在此之后,客户端将收到一个“什么都没发生”的响应,然后客户端将发出相同的请求。
为了让生活变得更加复杂,我想到的应用程序通过 HTTP/HTML5 和一个非常紧凑的 UDP 协议为 MIDP 客户端提供所有内容。来自任一协议的事件都可以释放任一协议中的响应。
TIA,阿德里安。
我可以在 Yesod 或任何其他具有类似数据库设施的 Haskell Web 框架中进行长轮询吗?
准确地说,我想延迟 HTTP 响应,直到发生有趣的事情。还应该有一个超时,在此之后,客户端将收到一个“什么都没发生”的响应,然后客户端将发出相同的请求。
为了让生活变得更加复杂,我想到的应用程序通过 HTTP/HTML5 和一个非常紧凑的 UDP 协议为 MIDP 客户端提供所有内容。来自任一协议的事件都可以释放任一协议中的响应。
TIA,阿德里安。
我无法回答更复杂的 UDP 内容的所有问题,但简短的回答是,是的,Yesod 支持长轮询。您基本上可以执行以下操作:
myHandler = do
mres <- timeout timeoutInMicroseconds someAction
case mres of
Nothing -> return nothingHappenedResponse
Just res -> doSomething res
您可能希望使用来自提升基础包的 System.Timeout.Lifted。
迈克尔的回答达到了超时要求。对于一般客户端,您不希望让 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 线程之间共享。