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