1

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.

Subhas
  • 14,290
  • 1
  • 29
  • 37
Piccolo
  • 1,612
  • 4
  • 22
  • 38
  • which server do you use and which sinata version? – Sir l33tname May 14 '13 at 07:55
  • @SirScript I use Thin (or WEBrick for development), and Sinatra 1.4.2 – Piccolo May 15 '13 at 01:16
  • http://www.sinatrarb.com/intro.html: "Some servers, like WEBRick, might not even support streaming at all." – utapyngo May 31 '13 at 13:25
  • @utapyngo Oh, that's why my app wouldn't work on Heroku. But the stream definitely works on Thin. It just doesn't recognize when users leave. – Piccolo Jun 01 '13 at 20:28
  • 1
    What I'd say is to not worry about it. Use `onbeforeunload`, and if someone is trying so hard not to leave the room, just to a inactivity based kick. – Linuxios Jun 03 '13 at 02:40

1 Answers1

2

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

Thiago Lewin
  • 2,810
  • 14
  • 18
  • Thanks so much! This is a really nice implementation. What license can I use this code under (not copied directly)? I was planning on releasing this project under the MIT license, would that be fine with you? I'll make sure to give you attribution. – Piccolo Jun 05 '13 at 01:20
  • MIT is fine for me! If you need something, let me know! – Thiago Lewin Jun 05 '13 at 11:06