Bytestring
ソース ( ) からのストリーミングのシンクをシミュレートするためにファイル ハンドルを使用するコードがありますAWS S3
。シンクとして使用したい場合は、以下のコードを(接続へのハンドルを使用して)Network.Websocket
交換するだけで十分でしょうか?LBS.writeFile
sendBinaryData
{-# LANGUAGE OverloadedStrings,ScopedTypeVariables #-}
import qualified Aws
import qualified Aws.S3 as S3
import Data.Conduit (($$+-))
import qualified Data.Conduit.List as CL (mapM_)
import qualified Data.ByteString.Streaming.HTTP as SP
import qualified Data.ByteString.Lazy as LBS
import Streaming as S
import Streaming.Prelude as S hiding (show,print)
import Control.Concurrent.Async (async,waitCatch)
import Data.Text as T (Text)
data AwsConfig a = AwsConfig { _aws_cfg :: Aws.Configuration, _aws_s3cfg :: S3.S3Configuration a, _aws_httpmgr :: SP.Manager }
getObject :: AwsConfig Aws.NormalQuery -> T.Text -> T.Text -> IO Int
getObject cfg bucket key = do
req <- waitCatch =<< async (runResourceT $ do
{- Create a request object with S3.getObject and run the request with pureAws. -}
S3.GetObjectResponse { S3.gorResponse = rsp, S3.gorMetadata = mdata } <-
Aws.pureAws (_aws_cfg cfg) (_aws_s3cfg cfg) (_aws_httpmgr cfg) $
S3.getObject bucket key
{- Stream the response to a lazy bytestring -}
liftIO $ LBS.writeFile "testaws" LBS.empty -- this will be replaced by content-length of the bytes
let obj = (($$+- CL.mapM_ S.yield) . hoist lift ) (SP.responseBody rsp)
S.mapM_ (liftIO . (LBS.appendFile "testaws") . LBS.fromStrict) obj
return $ lookup "content-length" (S3.omUserMetadata mdata))
case req of
Left _ -> return 2 -- perhaps, we could use this to send an error message over websocket
Right _ -> return 0
私にとって混乱の原因は、ストリームの終了がどのように決定されるかです? ファイルの場合、これはwriteFile
API によって処理されます。どうsendBinaryData
ですか?と同様に終了を処理しますwriteFile
か? それとも、クライアント側のデータ パーサーによって決定されますか?
アップデート
この質問は、上記の例のファイル ハンドルで行うように、Websocket ハンドル (ハンドルが提供されていると仮定します) にデータをストリーミングする方法に関するものであり、実際には 内でハンドルを管理する方法に関するものではありませんresourceT
。データをシンクするアプローチconduit
を取っているようです。mapM_
ですから、それは確かに進むべき道のようです。
終了に関する質問は、私が持っているこの考え方によるものです。Websocket ハンドルの反対側でデータをリッスンする関数がある場合、メッセージの終了を決定することは、ストリーミング コンテキストでは重要なようです。以下のような関数が与えられます:
f :: LBS.ByteString -> a
データを websocket ハンドルにストリーミングする場合S.mapM_
、何らかのend of stream
マーカーを追加f
して、反対側でリッスンしているときに遅延バイト文字列の処理を停止できるようにしますか? そうf
しないと、メッセージがいつ完了したかわかりません。