Search code examples
rubyhtmlsinatrawebsocketserver-sent-events

Handling event-stream connections in a Sinatra app


There is a great example of a chat app using Server-Sent Events by Konstantin Haase. I am trying to run it and have a problem with callbacks (I use Sinatra 1.3.2 and browse with Chrome 16). They simply do not run (e.g. after page reload), and therefore the number of connections is growing.

Also, connection is closed in 30-60 sec unless one sets a periodic timer to send empty data, as suggested by Konstantin elsewhere.

Can you replicate it? If yes, is it possible to fix these issues somehow? WebSockets work seamlessly in this respect...

# ruby
get '/stream', provides: 'text/event-stream' do
  stream :keep_open do |out|
    EventMachine::PeriodicTimer.new(20) { out << "data: \n\n" } # 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

Solution

  • This was a bug in Sinatra https://github.com/sinatra/sinatra/issues/446