2

我用来将'sControl.Monad.Managed包装在一个延续转换器中,但我还想在之后将 HTTP 响应流式传输出去:pipes-httpwithHTTP

import Pipes
import Pipes.ByteString
import Pipes.HTTP
import Control.Applicative
import Control.Monad
import Control.Monad.Managed
import qualified Data.ByteString.Char8       as BC

type RespBody = BC.ByteString

managedHTTP :: Request -> Manager -> Managed (Response (Producer RespBody IO ()))
managedHTTP r m = managed (withHTTP r m)

fromHTTP :: Request -> Manager -> Producer RespBody IO ()
fromHTTP request manager = join $ liftIO $ fmap (hoist liftIO) $ with response return
  where response = responseBody <$> managedHTTP request manager 

fromHTTP是为了流出响应体。如果以上运行:

main = do
  request <- parseUrl "http://en.wikipedia.org/"
  manager <- newManager defaultManagerSettings
  runEffect $ fromHTTP request manager >-> stdout

recv: invalid argument (Bad file descriptor)在第一块之后得到,因为http-client'responseClose已经关闭了我的响应正文。

with如果我想公开一个非样式接口,我应该如何使用管道流式传输 HTTP 响应?

如果我严重误解了延续和管道,谢谢并道歉。

4

1 回答 1

1

您的定义fromHTTP有点难以理解,但它显然让您在实际开始使用生产者之前退出托管环境。这样的事情可能更接近你的意图:

import Pipes
import Pipes.ByteString
import Pipes.HTTP
import Control.Applicative
import Control.Monad
import Control.Monad.Managed
import qualified Data.ByteString.Char8       as BC

type RespBody = BC.ByteString

managedHTTP :: Request -> Manager -> Managed (Response (Producer RespBody IO ()))
managedHTTP r m = managed (withHTTP r m)

managedManager :: ManagerSettings -> Managed Manager
managedManager settings = managed (withManager settings)

main = runManaged $ 
  do request <- liftIO $ parseUrl "http://en.wikipedia.org/" 
     manager <-  managedManager defaultManagerSettings
     producer <- managedHTTP request manager
     liftIO $ runEffect $ responseBody producer >-> stdout

或者只是废弃定义并编写

main = runManaged $ 
  do request  <- liftIO $ parseUrl "http://en.wikipedia.org/" 
     manager  <- managed (withManager defaultManagerSettings)
     producer <- managed (withHTTP request manager)
     liftIO $ runEffect $ responseBody producer >-> stdout

请注意,您也可以让生产者在Managedmonad 中运行:

main = runManaged $ 
  do request  <- liftIO $ parseUrl "http://en.wikipedia.org/" 
     manager  <- managed (withManager defaultManagerSettings)
     producer <- managed (withHTTP request manager)
     runEffect $ hoist liftIO (responseBody producer) >-> stdout
于 2014-09-09T15:30:31.587 回答