Added ajax messaging.

This commit is contained in:
Martin Edenhofer 2012-11-26 06:04:44 +01:00
parent 04264ffbb5
commit c7de6dfcc5
2 changed files with 79 additions and 29 deletions

View file

@ -5,23 +5,41 @@ module Session
@@user_threads = {} @@user_threads = {}
@@client_threads = {} @@client_threads = {}
def self.create( client_id, session ) def self.create( client_id, session, meta )
path = @path + '/' + client_id.to_s path = @path + '/' + client_id.to_s
FileUtils.mkpath path FileUtils.mkpath path
meta[:last_ping] = Time.new.to_i.to_s
File.open( path + '/session', 'w' ) { |file| File.open( path + '/session', 'w' ) { |file|
user = { :id => session['id'] } data = {
file.puts Marshal.dump(user) :user => {
:id => session['id'],
},
:meta => meta,
}
# puts 'CREATE' + Marshal.dump(data)
file.puts Marshal.dump(data)
} }
# send update to browser # send update to browser
if session['id'] if session['id']
self.transaction( client_id, { self.send( client_id, {
:event => 'ws:login', :event => 'ws:login',
:data => { :success => true }, :data => { :success => true },
}) })
end end
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 ) def self.get( client_id )
session_file = @path + '/' + client_id.to_s + '/session' session_file = @path + '/' + client_id.to_s + '/session'
data = nil data = nil
@ -40,9 +58,9 @@ module Session
return data return data
end end
def self.transaction( client_id, data ) def self.send( client_id, data )
path = @path + '/' + client_id.to_s + '/' 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 ) if File::exists?( path + filename )
filename = filename + '-1' filename = filename + '-1'
if File::exists?( path + filename ) if File::exists?( path + filename )
@ -73,10 +91,11 @@ module Session
next if @@client_threads[client_id] next if @@client_threads[client_id]
# get current user # get current user
user_session = Session.get( client_id ) session_data = Session.get( client_id )
next if !user_session next if !session_data
next if !user_session[:id] next if !session_data[:user]
user = User.find( user_session[:id] ) next if !session_data[:user][:id]
user = User.find( session_data[:user][:id] )
next if !user next if !user
# start user thread # start user thread
@ -125,7 +144,7 @@ module Session
path = @path + '/' + client_id.to_s + '/' path = @path + '/' + client_id.to_s + '/'
data = [] data = []
Dir.foreach( path ) do |entry| Dir.foreach( path ) do |entry|
if /^transaction/.match( entry ) if /^send/.match( entry )
data.push Session.queue_file( path, entry ) data.push Session.queue_file( path, entry )
end end
end end
@ -399,10 +418,11 @@ class ClientState
while true while true
# get connection user # get connection user
user_session = Session.get( @client_id ) session_data = Session.get( @client_id )
return if !user_session return if !session_data
return if !user_session[:id] return if !session_data[:user]
user = User.find( user_session[:id] ) return if !session_data[:user][:id]
user = User.find( session_data[:user][:id] )
return if !user return if !user
# set cache key # set cache key
@ -424,7 +444,7 @@ class ClientState
self.log 'notify', "push overview for user #{user.id}" self.log 'notify', "push overview for user #{user.id}"
# send update to browser # send update to browser
self.transaction({ self.send({
:event => 'navupdate_ticket_overview', :event => 'navupdate_ticket_overview',
:data => overview, :data => overview,
}) })
@ -471,7 +491,7 @@ class ClientState
} }
# send update to browser # send update to browser
self.transaction({ self.send({
:data => { :data => {
:overview => overview_data[:overview], :overview => overview_data[:overview],
:ticket_list => overview_data[:tickets], :ticket_list => overview_data[:tickets],
@ -510,7 +530,7 @@ class ClientState
self.log 'notify', "push ticket_create_attributes for user #{user.id}" self.log 'notify', "push ticket_create_attributes for user #{user.id}"
# send update to browser # send update to browser
self.transaction({ self.send({
:collection => 'ticket_create_attributes', :collection => 'ticket_create_attributes',
:data => data, :data => data,
}) })
@ -526,7 +546,7 @@ class ClientState
# send update to browser # send update to browser
r = CacheIn.get( cache_key + '_push', { :ignore_expire => true } ) r = CacheIn.get( cache_key + '_push', { :ignore_expire => true } )
self.transaction({ self.send({
:event => 'update_recent_viewed', :event => 'update_recent_viewed',
:data => r, :data => r,
}) })
@ -542,7 +562,7 @@ class ClientState
# send update to browser # send update to browser
r = CacheIn.get( cache_key + '_push', { :ignore_expire => true } ) r = CacheIn.get( cache_key + '_push', { :ignore_expire => true } )
self.transaction({ self.send({
:event => 'activity_stream_rebuild', :event => 'activity_stream_rebuild',
:collection => 'activity_stream', :collection => 'activity_stream',
:data => r, :data => r,
@ -559,7 +579,7 @@ class ClientState
# send update to browser # send update to browser
r = CacheIn.get( cache_key + '_push', { :ignore_expire => true } ) r = CacheIn.get( cache_key + '_push', { :ignore_expire => true } )
self.transaction({ self.send({
:event => 'rss_rebuild', :event => 'rss_rebuild',
:collection => 'dashboard_rss', :collection => 'dashboard_rss',
:data => r, :data => r,
@ -583,7 +603,7 @@ class ClientState
data = {} data = {}
data['collections'] = {} data['collections'] = {}
data['collections'][key] = push_collections data['collections'][key] = push_collections
self.transaction({ self.send({
:event => 'resetCollection', :event => 'resetCollection',
:data => data, :data => data,
}) })
@ -638,8 +658,8 @@ class ClientState
end end
# send update to browser # send update to browser
def transaction( data ) def send( data )
Session.transaction( @client_id, data ) Session.send( @client_id, data )
end end
def log( level, data ) def log( level, data )

View file

@ -129,7 +129,7 @@ EventMachine.run {
# get session # get session
if data['action'] == 'login' if data['action'] == 'login'
@clients[client_id][:session] = data['session'] @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 # remember ping, send pong back
elsif data['action'] == 'ping' elsif data['action'] == 'ping'
@ -165,9 +165,13 @@ EventMachine.run {
# check open unused connections, kick all connection without activitie in the last 5 minutes # check open unused connections, kick all connection without activitie in the last 5 minutes
EventMachine.add_periodic_timer(120) { EventMachine.add_periodic_timer(120) {
log 'notice', "check unused idle connections..." log 'notice', "check unused idle connections..."
idle_time_in_min = 4
# web sockets
@clients.each { |client_id, client| @clients.each { |client_id, client|
if ( client[:last_ping] + ( 60 * 4 ) ) < Time.now if ( client[:last_ping] + ( 60 * idle_time_in_min ) ) < Time.now
log 'notice', "closing idle connection", client_id log 'notice', "closing idle websocket connection", client_id
# remember to not use this connection anymore # remember to not use this connection anymore
client[:disconnect] = true client[:disconnect] = true
@ -180,18 +184,44 @@ EventMachine.run {
@clients.delete(client_id) @clients.delete(client_id)
end 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) { EventMachine.add_periodic_timer(20) {
log 'notice', "Status: clients: #{ @clients.size }"
# websocket
log 'notice', "Status: websocket clients: #{ @clients.size }"
@clients.each { |client_id, client| @clients.each { |client_id, client|
log 'notice', 'working...', client_id 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) { EventMachine.add_periodic_timer(0.4) {
next if @clients.size == 0 next if @clients.size == 0
log 'debug', "checking for data..." log 'debug', "checking for data to send..."
@clients.each { |client_id, client| @clients.each { |client_id, client|
next if client[:disconnect] next if client[:disconnect]
log 'debug', 'checking for data...', client_id log 'debug', 'checking for data...', client_id