当文件更新时,将文件内容流式传输到网页的最简单方法是什么。
我目前有一个.txt
在脚本运行时不断更新的文件,我想在更新时在页面上为用户显示该文件。
有没有简单的宝石或技术来实现这一点?或者有没有一个优秀的纯 Ruby 方法?
我的第一个想法是使用某种 AJAX 请求来返回文件的差异,但我觉得这是一个不好的方法。
我使用Tony Arcieri 的 Celluloid's Reel来完成此任务。
我在后台运行它(在这部分从Adam Dalton那里得到了很多帮助):
my_reel.rb
require 'reel'
CONNECTIONS = []
Reel::Server.supervise("0.0.0.0", 5000) do |connection|
while request = connection.request
case request
when Reel::Request
puts "Client requested: #{request.method} #{request.url} #{request.body}"
CONNECTIONS.each do |c|
c << request.body
end
request.respond :ok, 'YES! YOU GOT IT!'
when Reel::WebSocket
puts "Client made a WebSocket request to: #{request.url}"
CONNECTIONS << request
break
end
end
end
sleep
然后我编写了一个命令行脚本来向 Reel 服务器发送 post 请求。从Jesse Storimer 的编写尊重管道的 Ruby 脚本中获得了很多帮助。
~/bin/serve_it_up
#!/usr/bin/env ruby
require 'httparty'
ARGF.each_line do |line|
output_line = line.chop
HTTParty.post 'http://localhost:5000', body: output_line
end
然后为了使其工作,我的 Rails 应用程序使用 Sidekiq ( bundle exec sidekiq
),并在单击按钮时在后台运行脚本,将输出发送到文件output.txt
. 所以我运行一个强制尾部并将其输出到我的命令行脚本。
tail -f output.txt | serve_it_up
在我的网络应用程序中,我有一些 JavaScript(在本例中为咖啡脚本)连接到网络套接字并将输出放在页面上:
connection = new WebSocket('ws://localhost:5000')
connection.onmessage = (event) ->
$('#prompt').append(event.data + '<br/>')
prompt = document.getElementById('prompt')
prompt.scrollTop = prompt.scrollHeight
因此,只要 output.txt 发生变化,它就会从中获取输出tail -f
并将其放入 Web 浏览器中。我还将#prompt
div 设置为具有有限高度的样式,并且始终将其滚动到底部。
这是它的风格:
#prompt {
font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;
height: 200px;
overflow: auto;
}
您可以考虑使用 Faye 或 gem private_pub(它使 Faye 频道私有)之类的东西,它允许您使用 Web 套接字或长轮询将新数据推送到客户端。Github 页面上有很多文档,还有 RailsCast。
然后,在您的应用程序或脚本中,您可以发布到服务器,该服务器会将新数据推送到所有订阅的频道。