Puma ウェブサーバーは応答をバッファリングし続け、response.stream.close を呼び出すときに応答を送信します。
概要
設定した時間間隔でストリームにデータを書き込もうとしています。
class StreamController < ApplicationController
include ActionController::Live
def stream
response.headers['Content-Type'] = 'text/event-stream'
5.times do
response.stream.write "data: hello world\n\n"
sleep 1
end
ensure
response.stream.close
end
end
しかし、(curl を使用して) get リクエストを /stream エンドポイントに送信すると、次のメッセージが表示されます。「data: hello world
「データを受信する代わりに、5秒後に5回まとめて: hello world」
「1秒に1回。 私は Rails 7.0.4 に付属するデフォルトの puma Web サーバーを使用しています。私の推測では、応答をバッファリングしてから、response.stream.closeを呼び出すときに送信すると思います。
puma 設定ファイルに options = {lush_headers: true } を追加しようとしましたが、役に立ちませんでした。
解決策
ラックとピューマは長い間この問題を解決し、バグを修正してきました。公式には、rack v3 と puma v6 が必要ですが、rails 7 はrack v3 をサポートしていません。
私の知る限り、最後の問題は Rack::ETag ミドルウェアで、config.middleware.delete Rack::ETag を削除できます。しかし、おそらくそれが必要なので、現時点での回避策は次のとおりです。
class StreamController < ApplicationController
include ActionController::Live
def stream
response.headers["Content-Type"] = "text/event-stream"
# this bypasses etag calculation and magic happens
response.headers["Last-Modified"] = Time.now.httpdate
5.times {
response.stream.write "hello world\n"
sleep 1
}
ensure
response.stream.close
end
end
ETag: W/“53827b3eddcd709c853e748ffd5314fb” が表示される場合は、間違っています。
$ curl -i http://localhost:3000/stream/stream
HTTP/1.1 200 OK
Content-Type: text/event-stream
Last-Modified: Tue, 22 Aug 2023 10:29:34 GMT
Cache-Control: no-cache
X-Request-Id: 3dbb7f14-e167-4b5c-9cea-27c4ec131f24
X-Runtime: 0.094270
Server-Timing: start_processing.action_controller;dur=0.16
Transfer-Encoding: chunked
hello world
hello world
hello world
hello world
hello world
わかりませんが、ストリーミングしていました:) puma v6.3.1 ラック v2.2.7
https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://github.com/rack/rack/issues/1619