に基づいて他の質問への回答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つのデータチャンクをパイプに送信します。各チャンクは日付で始まり、dd
512バイトで埋められ、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
パイプラインの各タイムスタンプが表示され、接続に書き込まれます。read
sendto
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()
。