Search code examples
rubysinatraevent-stream

Detect when user leaves an event stream


I'm trying to make a chatroom from scratch using Sinatra. I need to detect when a user leaves the page. At first, I was thinking about using a Javascript onbeforeunload function, but then users could actually fake leaving or leave without notifying the server.

My code for the stream part looks like this:

get '/stream', :provides => 'text/event-stream' do
  stream :keep_open do |out|
    connections << out
  end
end

According to one of the Sinatra example files, chat.rb, which basically makes a chatroom, they use

out.callback do
   connections.delete(out)
end

but in my test, it didn't fire when I closed the page as a test (in my example, I had it puts something to the console if the code was fired, and nothing was outputted to the console).

Is there a more reliable way to detect if a user leaves the stream?

Also, I'm not using socket.io (client-side) or anything, but I'm open to it if it solves my problem.


Solution

  • Based on chat.rb example, I would create a small protocol to exchange data, instead of just clean chat messages.

    With this approach, you can send an "alive signal" for each connection and clean all that doesn't respond.

    I adapted a little the chat.rb to illustrate the idea: https://gist.github.com/tlewin/5708745