Unixパイプを使用したRESTサービスへのデータストリーミング

Unixパイプを使用したRESTサービスへのデータストリーミング

に基づいて他の質問への回答stdout要求されたエンティティにプロセスのストリームを取得するためにカールを使用していますPOST

myDataGeneratingApp \
| curl -H "Content-Type: application/json" -H "Transfer-Encoding: chunked" -X POST -d @- http://localhost:12000

EOF残念ながら、カールはデータ転送を開始する前に標準出力を待っています。私のアプリケーションはスタンドアロンで実行でき、データはすぐにコンソールに出力されるため、これを知っていますが、カールするようにパイプすると、サービスがデータの受信を開始する前に顕著な遅延が発生します。

アプリケーション標準で利用可能な場合、カールを使用してデータをすぐにストリーミングするにはどうすればよいですか?カールで不可能な場合は、他の解決策(wgetなど)がありますか?

ベストアンサー1

カールコードを見る転送.cプログラムは、チャンクプロトコルを使用して要求データ(カールからサーバーへ)を再パッケージできるように見えます。ここで、各データチャンクにはASCII 16進チャンク長が前に付けられます\r\n

サーバーに接続すると、ストリーミングを通じて利用可能に見えます-T -。次の例を考えてみましょう。

for i in $(seq 5)
do date
   sleep 1
done | 
dd conv=block cbs=512 |
strace -t -e sendto,read -o /tmp/e \
 curl --trace-ascii - \
 -H "Transfer-Encoding: chunked" \
 -H "Content-Type: application/json" \
 -X POST -T -  http://localhost/...

このスクリプトは5つのデータチャンクをパイプに送信します。各チャンクは日付で始まり、dd512バイトで埋められ、straceパイプcurl -T -を読み込みます。ターミナルでは、私たちは見ることができます

== Info: Connected to localhost (::1) port 80 (#0)
=> Send header, 169 bytes (0xa9)
0000: POST /... HTTP/1.1
001e: Host: localhost
002f: User-Agent: curl/7.47.1
0048: Accept: */*
0055: Transfer-Encoding: chunked
0071: Content-Type: application/json
0091: Expect: 100-continue
00a7: 
<= Recv header, 23 bytes (0x17)
0000: HTTP/1.1 100 Continue

送信された接続とヘッダーを表示します。特に、ヘッダーがcurl提供されず、サーバー(Apache)が応答したヘッダーが提供されます。その後、データの最初の512バイト(16進数200)が続きます。Content-length:Expect:Continue

=> Send data, 519 bytes (0x207)
0000: 200
0005: Fri Sep 14 15:58:15 CEST 2018                                   
0045:                                                                 
0085:                                                                 
00c5:                                                                 
0105:                                                                 
0145:                                                                 
0185:                                                                 
01c5:                                                                 
=> Send data, 519 bytes (0x207)

出力ファイルには、straceパイプラインの各タイムスタンプが表示され、接続に書き込まれます。readsendto

16:00:00 read(0, "Fri Sep 14 16:00:00 CEST 2018   "..., 16372) = 512
16:00:00 sendto(3, "200\r\nFri Sep 14 16:00:00 CEST 20"..., 519, ...) = 519
16:00:00 read(0, "Fri Sep 14 16:00:01 CEST 2018   "..., 16372) = 512
16:00:01 sendto(3, "200\r\nFri Sep 14 16:00:01 CEST 20"..., 519, ...) = 519
16:00:01 read(0, "Fri Sep 14 16:00:02 CEST 2018   "..., 16372) = 512
16:00:02 sendto(3, "200\r\nFri Sep 14 16:00:02 CEST 20"..., 519, ...) = 519
16:00:02 read(0, "Fri Sep 14 16:00:03 CEST 2018   "..., 16372) = 512
16:00:03 sendto(3, "200\r\nFri Sep 14 16:00:03 CEST 20"..., 519, ...) = 519
16:00:03 read(0, "Fri Sep 14 16:00:04 CEST 2018   "..., 16372) = 512
16:00:04 sendto(3, "200\r\nFri Sep 14 16:00:04 CEST 20"..., 519, ...) = 519
16:00:04 read(0, "", 16372)             = 0
16:00:05 sendto(3, "0\r\n\r\n", 5, ...) = 5

ご覧のとおり、2つの間隔は1秒で、データが受信されると同時に送信されていることを示します。データを読み込んでいるため、転送するには少なくとも512バイトが必要ですfread()

おすすめ記事