trabajo-afectivo/app/controllers/long_polling_controller.rb

162 lines
4.5 KiB
Ruby
Raw Normal View History

# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
2012-11-26 23:32:55 +00:00
class LongPollingController < ApplicationController
# GET /api/message_send
def message_send
new_connection = false
# check client id
client_id = client_id_check
if !client_id
new_connection = true
client_id = client_id_gen
log 'notice', "new client connection", client_id
2012-11-26 23:32:55 +00:00
else
# cerify client id
if !client_id_verify
render :json => { :error => 'Invalid client_id in send!' }, :status => :unprocessable_entity
return
end
end
if !params['data']
params['data'] = {}
end
# spool messages for new connects
if params['data']['spool']
msg = JSON.generate( params )
Session.spool_create(msg)
end
# get spool messages and send them to new client connection
if params['data']['action'] == 'spool'
log 'notice', "request spool data", client_id
spool = Session.spool_list( params['data']['timestamp'], current_user.id )
spool.each { |item|
if item[:type] == 'direct'
log 'notice', "send spool to (user_id=#{ current_user.id })", client_id
2013-06-17 05:38:17 +00:00
Session.send( client_id, item[:message]['data'] )
else
log 'notice', "send spool", client_id
2013-06-17 05:38:17 +00:00
Session.send( client_id, item[:message]['data'] )
end
}
# send spool:sent event to client
2013-06-17 05:38:17 +00:00
sleep 0.2
log 'notice', "send spool:sent event", client_id
Session.send( client_id, { :event => 'spool:sent' } )
end
2012-11-26 23:32:55 +00:00
# receive message
if params['data']['action'] == 'login'
user_id = session[:user_id]
user = {}
if user_id
user = User.user_data_full( user_id )
end
log 'notice', "send auth login (user_id #{user_id})", client_id
2012-11-26 23:32:55 +00:00
Session.create( client_id, user, { :type => 'ajax' } )
# broadcast
elsif params['data']['action'] == 'broadcast'
# list all current clients
client_list = Session.list
client_list.each {|local_client_id, local_client|
if local_client_id.to_s != client_id.to_s
# broadcast to recipient list
2013-06-10 20:19:11 +00:00
if params['data']['data']['recipient'] && params['data']['data']['recipient']['user_id']
params['data']['data']['recipient']['user_id'].each { |user_id|
if local_client[:user][:id] == user_id
log 'notice', "send broadcast from (#{client_id.to_s}) to (user_id #{user_id})", local_client_id
Session.send( local_client_id, params['data'] )
end
}
# broadcast every client
else
log 'notice', "send broadcast from (#{client_id.to_s})", local_client_id
Session.send( local_client_id, params['data'] )
end
else
log 'notice', "do not send broadcast to it self", client_id
end
}
2012-11-26 23:32:55 +00:00
end
if new_connection
result = { :client_id => client_id }
render :json => result
else
render :json => {}
end
end
# GET /api/message_receive
def message_receive
# check client id
if !client_id_verify
render :json => { :error => 'Invalid client_id receive!' }, :status => :unprocessable_entity
return
end
# check queue to send
2012-11-26 23:32:55 +00:00
client_id = client_id_check
begin
# update last ping
Session.touch( client_id )
# set max loop time to 28 sec. because of 30 sec. timeout of mod_proxy
count = 14
2012-11-26 23:32:55 +00:00
while true
count = count - 1
queue = Session.queue( client_id )
if queue && queue[0]
# puts "send " + queue.inspect + client_id.to_s
2012-11-26 23:32:55 +00:00
render :json => queue
return
end
sleep 2
if count == 0
render :json => { :action => 'pong' }
return
end
end
rescue Exception => e
puts e.inspect
puts e.backtrace
2012-11-26 23:32:55 +00:00
render :json => { :error => 'Invalid client_id in receive loop!' }, :status => :unprocessable_entity
return
end
end
private
def client_id_check
return params[:client_id] if params[:client_id]
return
end
def client_id_gen
rand(99999999)
end
def client_id_verify
return if !params[:client_id]
sessions = Session.sessions
return if !sessions.include?( params[:client_id].to_s )
return true
end
def log( level, data, client_id = '-' )
if false
return if level == 'debug'
end
puts "#{Time.now}:client(#{ client_id }) #{ data }"
# puts "#{Time.now}:#{ level }:client(#{ client_id }) #{ data }"
end
end