我可以在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
你可能会想要从lifted-base包中使用system . timeout . lifting
Michael的回答符合超时要求。对于一般客户端,您不希望让HTTP响应等待超过60秒,因为它们可能通过代理或类似的方式连接,这些代理或类似的方式在大约60秒后会变得不耐烦。如果你使用的是一个控制更严格的网络,那么你可以放松这个超时时间。一个小的修正是,timeout
的参数单位是微秒,而不是纳秒。
对于"等待有趣的事情发生"部分,我们使用Control.Concurrent.STM
中的check
组合子(它包含了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
。