在一个简单的 Rails 5 应用程序的单个 Controller 中,我有 2 个操作(live
和 test
),都使用 ActionController::Live
。 live
通过一个循环并将随机数据写入 response.stream.write
没有任何问题。它有效。
然而,在 test
中,我使用的是 Redis.subscribe。这是操作代码:
def test
response.headers['Content-Type'] = 'text/event-stream'
redis = Redis.new
redis.subscribe_with_timeout(30, "abc") do |on|
on.message do |event, data|
puts data
response.stream.write data
end
end
rescue IOError
# ignore
ensure
redis.quit
response.stream.close
end
然而,test
方法没有按预期工作。这是发生了什么:
我启动应用程序并使用 curl
访问 test
端点。 Curl 按预期停止等待数据。
然后在 redis-cli
中,我向 abc
channel 发送一条消息。我立即在 Rails 应用程序窗口中看到了我的消息(puts data
),我在 curl 中看到了这个:
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
X-Request-Id: 25df052d-e3f2-4327-9a97-088e702460fa
X-Runtime: 2.709001
Transfer-Encoding: chunked
但是,虽然来自 redis-cli
的所有后续消息都打印在 rails 端,但直到超时结束(subscribe_with_timeout
中的 30 秒)它们才会被 curl 接收>).
我正在运行 Puma,已经查看并实现了所有关于并发、心跳线程等的 Stackoverflow 答案,但没有成功。
最佳答案
经过大量挖掘后,结果证明您需要在任何输出到 response.stream.write
的内容末尾添加一个新行 "\n"
它离开缓冲区。
关于ruby-on-rails - Redis 订阅 + Rails ActionController::Live 挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56619324/