From c7de6dfcc5a84a619f526fb2ece4941fc27ee9d3 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Mon, 26 Nov 2012 06:04:44 +0100 Subject: [PATCH] Added ajax messaging. --- lib/session.rb | 68 ++++++++++++++++++++++++-------------- script/websocket-server.rb | 40 +++++++++++++++++++--- 2 files changed, 79 insertions(+), 29 deletions(-) diff --git a/lib/session.rb b/lib/session.rb index 5af5f7d0f..75e683662 100644 --- a/lib/session.rb +++ b/lib/session.rb @@ -5,23 +5,41 @@ module Session @@user_threads = {} @@client_threads = {} - def self.create( client_id, session ) + def self.create( client_id, session, meta ) path = @path + '/' + client_id.to_s FileUtils.mkpath path + meta[:last_ping] = Time.new.to_i.to_s File.open( path + '/session', 'w' ) { |file| - user = { :id => session['id'] } - file.puts Marshal.dump(user) + data = { + :user => { + :id => session['id'], + }, + :meta => meta, + } +# puts 'CREATE' + Marshal.dump(data) + file.puts Marshal.dump(data) } # send update to browser if session['id'] - self.transaction( client_id, { + self.send( client_id, { :event => 'ws:login', :data => { :success => true }, }) end end + def self.list + client_ids = self.sessions + session_list = {} + client_ids.each { |client_id| + data = self.get(client_id) + next if !data + session_list[client_id] = data + } + return session_list + end + def self.get( client_id ) session_file = @path + '/' + client_id.to_s + '/session' data = nil @@ -40,9 +58,9 @@ module Session return data end - def self.transaction( client_id, data ) + def self.send( client_id, data ) path = @path + '/' + client_id.to_s + '/' - filename = 'transaction-' + Time.new().to_i.to_s + '-' + rand(999999).to_s + filename = 'send-' + Time.new().to_i.to_s + '-' + rand(999999).to_s if File::exists?( path + filename ) filename = filename + '-1' if File::exists?( path + filename ) @@ -73,10 +91,11 @@ module Session next if @@client_threads[client_id] # get current user - user_session = Session.get( client_id ) - next if !user_session - next if !user_session[:id] - user = User.find( user_session[:id] ) + session_data = Session.get( client_id ) + next if !session_data + next if !session_data[:user] + next if !session_data[:user][:id] + user = User.find( session_data[:user][:id] ) next if !user # start user thread @@ -125,7 +144,7 @@ module Session path = @path + '/' + client_id.to_s + '/' data = [] Dir.foreach( path ) do |entry| - if /^transaction/.match( entry ) + if /^send/.match( entry ) data.push Session.queue_file( path, entry ) end end @@ -399,10 +418,11 @@ class ClientState while true # get connection user - user_session = Session.get( @client_id ) - return if !user_session - return if !user_session[:id] - user = User.find( user_session[:id] ) + session_data = Session.get( @client_id ) + return if !session_data + return if !session_data[:user] + return if !session_data[:user][:id] + user = User.find( session_data[:user][:id] ) return if !user # set cache key @@ -424,7 +444,7 @@ class ClientState self.log 'notify', "push overview for user #{user.id}" # send update to browser - self.transaction({ + self.send({ :event => 'navupdate_ticket_overview', :data => overview, }) @@ -471,7 +491,7 @@ class ClientState } # send update to browser - self.transaction({ + self.send({ :data => { :overview => overview_data[:overview], :ticket_list => overview_data[:tickets], @@ -510,7 +530,7 @@ class ClientState self.log 'notify', "push ticket_create_attributes for user #{user.id}" # send update to browser - self.transaction({ + self.send({ :collection => 'ticket_create_attributes', :data => data, }) @@ -526,7 +546,7 @@ class ClientState # send update to browser r = CacheIn.get( cache_key + '_push', { :ignore_expire => true } ) - self.transaction({ + self.send({ :event => 'update_recent_viewed', :data => r, }) @@ -542,7 +562,7 @@ class ClientState # send update to browser r = CacheIn.get( cache_key + '_push', { :ignore_expire => true } ) - self.transaction({ + self.send({ :event => 'activity_stream_rebuild', :collection => 'activity_stream', :data => r, @@ -559,7 +579,7 @@ class ClientState # send update to browser r = CacheIn.get( cache_key + '_push', { :ignore_expire => true } ) - self.transaction({ + self.send({ :event => 'rss_rebuild', :collection => 'dashboard_rss', :data => r, @@ -583,7 +603,7 @@ class ClientState data = {} data['collections'] = {} data['collections'][key] = push_collections - self.transaction({ + self.send({ :event => 'resetCollection', :data => data, }) @@ -638,8 +658,8 @@ class ClientState end # send update to browser - def transaction( data ) - Session.transaction( @client_id, data ) + def send( data ) + Session.send( @client_id, data ) end def log( level, data ) diff --git a/script/websocket-server.rb b/script/websocket-server.rb index 8b14a5809..4863f35c2 100644 --- a/script/websocket-server.rb +++ b/script/websocket-server.rb @@ -129,7 +129,7 @@ EventMachine.run { # get session if data['action'] == 'login' @clients[client_id][:session] = data['session'] - Session.create( client_id, data['session'] ) + Session.create( client_id, data['session'], { :type => 'websocket' } ) # remember ping, send pong back elsif data['action'] == 'ping' @@ -165,9 +165,13 @@ EventMachine.run { # check open unused connections, kick all connection without activitie in the last 5 minutes EventMachine.add_periodic_timer(120) { log 'notice', "check unused idle connections..." + + idle_time_in_min = 4 + + # web sockets @clients.each { |client_id, client| - if ( client[:last_ping] + ( 60 * 4 ) ) < Time.now - log 'notice', "closing idle connection", client_id + if ( client[:last_ping] + ( 60 * idle_time_in_min ) ) < Time.now + log 'notice', "closing idle websocket connection", client_id # remember to not use this connection anymore client[:disconnect] = true @@ -180,18 +184,44 @@ EventMachine.run { @clients.delete(client_id) end } + + # ajax + clients = Session.list + clients.each { |client_id, client| + next if client[:meta][:type] == 'websocket' + if ( client[:meta][:last_ping].to_i + ( 60 * idle_time_in_min ) ) < Time.now.to_i + log 'notice', "closing idle ajax connection", client_id + Session.destory( client_id ) + end + } } EventMachine.add_periodic_timer(20) { - log 'notice', "Status: clients: #{ @clients.size }" + + # websocket + log 'notice', "Status: websocket clients: #{ @clients.size }" @clients.each { |client_id, client| log 'notice', 'working...', client_id } + + # ajax + client_list = Session.list + clients = 0 + client_list.each {|client_id, client| + next if client[:meta][:type] == 'websocket' + clients = clients + 1 + } + log 'notice', "Status: ajax clients: #{ clients }" + client_list.each {|client_id, client| + next if client[:meta][:type] == 'websocket' + log 'notice', 'working...', client_id + } + } EventMachine.add_periodic_timer(0.4) { next if @clients.size == 0 - log 'debug', "checking for data..." + log 'debug', "checking for data to send..." @clients.each { |client_id, client| next if client[:disconnect] log 'debug', 'checking for data...', client_id