我正在制作一个简单的rails(3.2.11)演示,只有我才能访问。我有以下内容:
1)名为Food的Rails脚手架
2)一个Android设备,可以调用自定义路由/控制器,然后创建一个新的Food。 (Food.create...
)。
因此,在我的计算机浏览器上,我加载了http://myapp.com
,它正在托管rails应用程序。它立即加载所有食物,因为它呈现foods#index
。然而,当我通过从我的Android设备调用创建一个新的Food
时,浏览器页面(在我的计算机上)仍然显示旧的食物列表,即使数据库知道有新的食物。 (因为此时我还没有刷新页面)
当数据库更改为Food
表时,如何添加“侦听器/观察器”以自动刷新页面?这有可能吗?
我不是在寻找<meta http-equiv="refresh" content="5">
,因为我希望在整个30分钟的演示过程中保持计算机的浏览器开启状态。
=================
另外,我在3年多没有使用过rails,所以如果你有足够的回答,请解释一下,以便初学者能理解? (首选明确的细节)
答案 0 :(得分:1)
查看EventSource或WebSockets进行实时开发。还有其他替代方案,如长期投票。但是,如果要从同一页面添加新食物,则可以轻松捕获该事件并刷新数据。
答案 1 :(得分:1)
答案 2 :(得分:1)
过去,常见的选择是使用 Juggernaut 将数据从服务器推送到客户端。它甚至在websockets被广泛使用之前就被使用了,但它最近被弃用,而不是支持 HTML5 Server-Sent-Events (SSE)。要使用SSE,您应该像这样应用客户端侦听器:
var source = new EventSource('/stream');
source.addEventListener('message', function(e) {
console.log('Received a message:', e.data);
//fetch new data with AJAX, or reload
location.reload();
});
服务器端,有很多方法可以发送事件。使用Cramp,发送事件就像这样(取自文档):
class TimeAction < Cramp::Action
self.transport = :sse
#set the transport to Server-Sent Event
on_start :send_latest_time
periodic_timer :send_latest_time, :every => 2
def send_latest_time
data = {'time' => Time.now.to_i}.to_json
render data
end
end
如果您正在使用Sinatra,您的代码将如下所示:
get '/stream', :provides => 'text/event-stream' do
stream :keep_open do |out|
connections << out
out.callback { connections.delete(out) }
end
end
除了Internet Explorer和Opera Mini之外,大多数浏览器都支持服务器发送的事件,但是有一些回退/ polyfill库,例如here或here(jQuery解决方案)。与websockets不同,它们仍然使用HTTP协议,但请记住它们是单向的,而websockets可用于多向通信。如果您对SSE和websockets之间的差异感到好奇,请参阅here。