Search code examples
apachesinatrathinserver-sent-events

Server Sent Event connection not staying open with Apache/Thin/Sinatra


I'm trying to setup basic server side event ability using Apache/Thin/Sinatra. Everything works as exepcted when I run the Thin server directly. When I run the Thin server through Apache using the RackBaseURI config setting, everything still works, but the connection is not persisted. It goes through a cycle of opening, writing some data to the browser and immediately closing. Seems like an Apache configuration issue?

I've gone through the Apache config and don't see anything that seems like it would prevent an open connection. Because I'm not sure where the error is, I don't want to post endless configuration data, so I can include more if I'm missing something...

sinatra (1.3.4), thin (1.5.0), Apache/2.2.22 (Ubuntu), ruby 1.8.7

The JavaScript...

$j(function(){

  console.log("Starting...");

  var es = new EventSource("/stream_event");

  es.addEventListener('message', function(e) {
    console.log(e.data);
  }, false);

  es.addEventListener('open', function(e) {
    console.log("Connection Open");
  }, false);

  es.addEventListener('error', function(e) {
    console.log("error = " + e.eventPhase)
    if (e.eventPhase == EventSource.CLOSED) {
      console.log("Connection Closed");
    }
  }, false);
}

The server side sinatra/ruby..

set :server, :thin
connections = []

get '/' do
  content_type 'text/event-stream'
  stream(:keep_open) { |out| 
    connections << out
    out << "data: hello\n\n" 
  }
end

get '/post_message' do
  connections.each { |out| out << params[:message] << "\n" }
  "message sent"
end

EDIT:

And here's the output I see in the browser console ...

Connection Open
hello
error = 2
Connection Closed
Connection Open
hello
error = 2
Connection Closed 
Connection Open
hello
error = 2
Connection Closed 
Connection Open
hello
error = 2
Connection Closed 
Connection Open
hello
error = 2
Connection Closed  

Solution

  • Seems to be something related to the RackBaseURI configuration setting. I was able to get things working by removing that attribute and directing the traffic to my Sinatra app using Apache's proxy abilities...

    ProxyPass /stream_event http://127.0.0.1:9292
    ProxyPassReverse /stream_event http://127.0.0.1:9292
    

    The primary disadvantage here is that I need to startup and monitor the running Sinatra app manually using some other process.