2021-06-01 12:20:20 +00:00
|
|
|
# Copyright (C) 2012-2021 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
|
2017-09-23 06:25:55 +00:00
|
|
|
skip_before_action :session_update # prevent race conditions
|
2018-11-02 17:42:57 +00:00
|
|
|
prepend_before_action :authentication_check_only
|
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
|
2018-11-02 17:42:57 +00:00
|
|
|
data = params['data'].permit!.to_h
|
2015-12-09 13:09:37 +00:00
|
|
|
session_data = {}
|
2017-11-23 08:09:44 +00:00
|
|
|
if current_user&.id
|
2015-12-09 13:09:37 +00:00
|
|
|
session_data = { 'id' => current_user.id }
|
|
|
|
end
|
2012-11-26 23:32:55 +00:00
|
|
|
|
2013-06-10 07:01:37 +00:00
|
|
|
# spool messages for new connects
|
2018-11-02 17:42:57 +00:00
|
|
|
if data['spool']
|
|
|
|
Sessions.spool_create(data)
|
2013-06-10 07:01:37 +00:00
|
|
|
end
|
2018-11-02 17:42:57 +00:00
|
|
|
if data['event'] == 'login'
|
2015-12-09 13:09:37 +00:00
|
|
|
Sessions.create(client_id, session_data, { type: 'ajax' })
|
2018-11-02 17:42:57 +00:00
|
|
|
elsif data['event']
|
2015-12-09 13:09:37 +00:00
|
|
|
message = Sessions::Event.run(
|
2018-12-19 17:31:51 +00:00
|
|
|
event: data['event'],
|
|
|
|
payload: data,
|
|
|
|
session: session_data,
|
2015-12-09 13:09:37 +00:00
|
|
|
client_id: client_id,
|
2018-12-19 17:31:51 +00:00
|
|
|
clients: {},
|
|
|
|
options: {},
|
2015-12-09 13:09:37 +00:00
|
|
|
)
|
|
|
|
if message
|
|
|
|
Sessions.send(client_id, message)
|
2013-06-30 15:54:54 +00:00
|
|
|
end
|
2015-12-09 13:09:37 +00:00
|
|
|
else
|
2018-11-02 17:42:57 +00:00
|
|
|
log "unknown message '#{data.inspect}'", client_id
|
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
|
2018-11-02 17:42:57 +00:00
|
|
|
return
|
2012-11-26 23:32:55 +00:00
|
|
|
end
|
2018-11-02 17:42:57 +00:00
|
|
|
render json: {}
|
2012-11-26 23:32:55 +00:00
|
|
|
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
|
2016-06-30 08:24:03 +00:00
|
|
|
raise Exceptions::UnprocessableEntity, 'Invalid client_id receive!' if !client_id
|
2012-11-26 23:32:55 +00:00
|
|
|
|
2013-06-11 06:17:50 +00:00
|
|
|
# check queue to send
|
2012-11-26 23:32:55 +00:00
|
|
|
begin
|
2013-06-11 06:17:50 +00:00
|
|
|
# update last ping
|
2017-10-01 12:25:52 +00:00
|
|
|
4.times do
|
2013-08-28 06:40:02 +00:00
|
|
|
sleep 0.25
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2021-07-16 13:44:10 +00:00
|
|
|
# sleep 1
|
2017-11-23 08:09:44 +00:00
|
|
|
Sessions.touch(client_id) # rubocop:disable Rails/SkipsModelValidations
|
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
|
2015-12-09 13:09:37 +00:00
|
|
|
count = 3
|
|
|
|
if Rails.env.production?
|
|
|
|
count = 12
|
|
|
|
end
|
2015-05-05 14:10:06 +00:00
|
|
|
loop do
|
2021-07-16 14:10:31 +00:00
|
|
|
count -= 1
|
2015-12-09 13:09:37 +00:00
|
|
|
queue = Sessions.queue(client_id)
|
2012-11-26 23:32:55 +00:00
|
|
|
if queue && queue[0]
|
2018-03-20 17:47:49 +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
|
2017-10-01 12:25:52 +00:00
|
|
|
8.times do
|
2013-08-28 06:40:02 +00:00
|
|
|
sleep 0.25
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2021-07-16 13:44:10 +00:00
|
|
|
# sleep 2
|
2016-01-16 10:05:04 +00:00
|
|
|
if count.zero?
|
2015-12-09 13:09:37 +00:00
|
|
|
render json: { event: 'pong' }
|
2012-11-26 23:32:55 +00:00
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
2019-06-28 11:38:49 +00:00
|
|
|
rescue
|
2016-06-30 08:24:03 +00:00
|
|
|
raise Exceptions::UnprocessableEntity, 'Invalid client_id in receive loop!'
|
2012-11-26 23:32:55 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
2013-09-19 14:56:09 +00:00
|
|
|
|
2013-06-12 15:59:58 +00:00
|
|
|
def client_id_gen
|
2021-09-20 10:47:05 +00:00
|
|
|
SecureRandom.uuid
|
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]
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2013-08-21 18:35:22 +00:00
|
|
|
sessions = Sessions.sessions
|
2020-09-30 09:07:01 +00:00
|
|
|
return if sessions.exclude?(params[:client_id].to_s)
|
2018-10-09 06:17:41 +00:00
|
|
|
|
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
|
|
|
|
2018-11-02 17:42:57 +00:00
|
|
|
def log(data, client_id = '-')
|
2015-07-03 15:18:01 +00:00
|
|
|
logger.info "client(#{client_id}) #{data}"
|
2013-06-12 15:59:58 +00:00
|
|
|
end
|
2013-06-10 07:01:37 +00:00
|
|
|
end
|