Konstantin Haase有一个使用服务器发送事件的聊天应用程序的好例子。我试图运行它,并有回调的问题(我使用Sinatra 1.3.2和Chrome 16浏览)。它们根本不运行(例如,在页面重新加载后),因此连接数正在增长。
此外,连接将在30-60秒内关闭,除非像Konstantin在其他地方建议的那样设置周期性计时器来发送空数据。
你能复制吗?如果是,是否有可能以某种方式解决这些问题?WebSockets在这方面可以无缝地工作…
# ruby
get '/stream', provides: 'text/event-stream' do
stream :keep_open do |out|
EventMachine::PeriodicTimer.new(20) { out << "data: nn" } # added
settings.connections << out
puts settings.connections.count # added
out.callback { puts 'closed'; settings.connections.delete(out) } # modified
end
end
# javascript
var es = new EventSource('/stream');
es.onmessage = function(e) { if (e.data != '') $('#chat').append(e.data + "n") }; // modified
这是Sinatra中的一个bug https://github.com/sinatra/sinatra/issues/446
整洁的代码。但是你是对的,WebSockets可以解决这些问题。我认为这里有两个问题:
1)您的浏览器、Web服务器或中间的代理可能会在一段时间后关闭您的连接,无论是否空闲。你建议的发送空数据的定时计时器会有帮助,但不能保证。
2)据我所知,没有内置的方法来判断这些连接是否/何时仍在工作。为了防止连接列表增长,您必须跟踪每个连接最后一次"使用"的时间(可能客户端偶尔应该ping,并且您将存储此日期时间)。然后添加一个定时计时器来检查和终止"陈旧"的连接。
一个更简单(虽然可能更难看)的选择是存储每个连接的创建时间,并在n分钟后终止它。客户端应该足够聪明,可以重新连接。
我知道这会使代码失去一些简单性。这个例子很简洁,我认为它是WebSockets的一个更好的候选。