哈斯克尔仆人和流媒体



我正在尝试向我的servant服务器添加一个功能,该功能将从 Amazon S3 获取文件并将其流式传输回用户。由于文件可能很大,我不想在本地下载它们,然后将它们提供给客户端,所以我宁愿将它们直接从 S3 流式传输到客户端。

我使用 Amazonka 执行 S3 的操作,并且可以获取 S3 文件的流作为Conduit接收器。

但是现在我不知道如何从SinkEitherT ServantErr IO a.

谁能解释我如何做到这一点或给我看一些如何做到这一点的例子?

Servant 中没有开箱即用的功能,但是所有需要的零件都可用。

在我们开始之前,我想如果你可以流式传输到接收器,那就意味着你有一个源(GetObjectResponsegorsBody是一个RsBody,这是一个源)

首先,Servant 为我们提供了添加对新返回类型的支持的可能性,方法是创建一个新的 HasServer 实例,这样我们就可以提供EitherT ServantErr IO (Source ...)并使其流式传输。

要创建该实例,我们必须实现 route :: Proxy layout -> Server layout -> RoutingApplication . Server layout ,在这种情况下,只是意味着 EitherT ServantErr IO layoutlayout是我们想要服务器的源,因此它是返回源的函数(并且可能会因 HTTP 错误而失败)。

我们必须返回一个 RoutingApplication ,它是(在延续样式中)一个接受Request并返回一个 RouteResult Response 的函数,这意味着不匹配的路由错误或响应。RequestResponse都是标准的wai,而不是Servant,所以我们现在可以看看生态系统的其余部分,找到如何实现它。

幸运的是,我们不必走得太远:Network.Wai.Conduit只包含实现route函数所需的内容:responseSource获取状态值、一些响应标头和您的源,并为您提供Response

所以,这是相当多的工作要做,但我们需要的一切都在那里。查看实例HasServer * (Get ...)源可能会有所帮助。