trabajo-afectivo/app/controllers/long_polling_controller.rb

165 lines
4.4 KiB
Ruby
Raw Normal View History

2014-02-03 19:24:49 +00:00
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
2012-11-26 23:32:55 +00:00
class LongPollingController < ApplicationController
skip_filter :session_update
2012-11-26 23:32:55 +00:00
# GET /api/v1/message_send
2012-11-26 23:32:55 +00:00
def message_send
new_connection = false
# check client id
client_id = client_id_verify
2012-11-26 23:32:55 +00:00
if !client_id
new_connection = true
client_id = client_id_gen
2015-05-04 18:58:28 +00:00
log 'new client connection', client_id
2012-11-26 23:32:55 +00:00
end
if !params['data']
params['data'] = {}
end
# spool messages for new connects
if params['data']['spool']
2013-06-28 22:26:04 +00:00
msg = JSON.generate( params['data'] )
Sessions.spool_create(msg)
end
# get spool messages and send them to new client connection
if params['data']['action'] == 'spool'
# error handling
if params['data']['timestamp']
log "request spool data > '#{Time.zone.at( params['data']['timestamp'] )}'", client_id
else
2015-05-04 18:58:28 +00:00
log 'request spool init data', client_id
end
if current_user
spool = Sessions.spool_list( params['data']['timestamp'], current_user.id )
spool.each { |item|
if item[:type] == 'direct'
2015-05-04 18:58:28 +00:00
log "send spool to (user_id=#{ current_user.id })", client_id
Sessions.send( client_id, item[:message] )
else
2015-05-04 18:58:28 +00:00
log 'send spool', client_id
Sessions.send( client_id, item[:message] )
end
}
end
# send spool:sent event to client
2013-06-17 05:38:17 +00:00
sleep 0.2
2015-05-04 18:58:28 +00:00
log 'send spool:sent event', client_id
Sessions.send( client_id, { event: 'spool:sent', data: { timestamp: Time.zone.now.utc.to_i } } )
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.find( user_id ).attributes
2012-11-26 23:32:55 +00:00
end
2015-05-04 18:58:28 +00:00
log "send auth login (user_id #{user_id})", client_id
Sessions.create( client_id, user, { type: 'ajax' } )
# broadcast
elsif params['data']['action'] == 'broadcast'
# list all current clients
client_list = Sessions.list
client_list.each {|local_client_id, local_client|
if local_client_id != client_id
# broadcast to recipient list
2013-06-28 22:26:04 +00:00
if params['data']['recipient'] && params['data']['recipient']['user_id']
params['data']['recipient']['user_id'].each { |loop_user_id|
if local_client[:user]['id'].to_s == loop_user_id.to_s
log "send broadcast from (#{client_id}) to (user_id #{loop_user_id})", local_client_id
Sessions.send( local_client_id, params['data'] )
end
}
# broadcast every client
else
2015-05-04 18:58:28 +00:00
log "send broadcast from (#{client_id})", local_client_id
Sessions.send( local_client_id, params['data'] )
end
else
2015-05-04 18:58:28 +00:00
log '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
2012-11-26 23:32:55 +00:00
else
render json: {}
2012-11-26 23:32:55 +00:00
end
end
# GET /api/v1/message_receive
2012-11-26 23:32:55 +00:00
def message_receive
# check client id
client_id = client_id_verify
if !client_id
render json: { error: 'Invalid client_id receive!' }, status: :unprocessable_entity
2012-11-26 23:32:55 +00:00
return
end
# check queue to send
2012-11-26 23:32:55 +00:00
begin
# update last ping
4.times {
sleep 0.25
}
#sleep 1
Sessions.touch( client_id )
# set max loop time to 24 sec. because of 30 sec. timeout of mod_proxy
count = 12
loop do
2012-11-26 23:32:55 +00:00
count = count - 1
queue = Sessions.queue( client_id )
2012-11-26 23:32:55 +00:00
if queue && queue[0]
2015-05-04 19:11:20 +00:00
logger.debug "send #{queue.inspect} to #{client_id}"
render json: queue
2012-11-26 23:32:55 +00:00
return
end
8.times {
sleep 0.25
}
#sleep 2
2012-11-26 23:32:55 +00:00
if count == 0
render json: { action: 'pong' }
2012-11-26 23:32:55 +00:00
return
end
end
rescue => e
2015-05-04 18:58:28 +00:00
logger.error e.inspect
logger.error e.backtrace
render json: { error: 'Invalid client_id in receive loop!' }, status: :unprocessable_entity
2012-11-26 23:32:55 +00:00
return
end
end
private
def client_id_gen
rand(9_999_999_999).to_s
end
def client_id_verify
return if !params[:client_id]
sessions = Sessions.sessions
return if !sessions.include?( params[:client_id].to_s )
2015-04-27 20:49:17 +00:00
params[:client_id].to_s
end
2015-05-04 18:58:28 +00:00
def log( data, client_id = '-' )
logger.info "client(#{ client_id }) #{ data }"
end
end