mirror of
https://github.com/zammad/zammad
synced 2026-05-24 09:48:36 +00:00
121 lines
2.8 KiB
Ruby
121 lines
2.8 KiB
Ruby
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
|
|
|
class LongPollingController < ApplicationController
|
|
skip_action_callback :session_update # prevent race conditions
|
|
|
|
# GET /api/v1/message_send
|
|
def message_send
|
|
new_connection = false
|
|
|
|
# check client id
|
|
client_id = client_id_verify
|
|
if !client_id
|
|
new_connection = true
|
|
client_id = client_id_gen
|
|
log 'new client connection', client_id
|
|
end
|
|
if !params['data']
|
|
params['data'] = {}
|
|
end
|
|
session_data = {}
|
|
if current_user && current_user.id
|
|
session_data = { 'id' => current_user.id }
|
|
end
|
|
|
|
# spool messages for new connects
|
|
if params['data']['spool']
|
|
Sessions.spool_create(params['data'])
|
|
end
|
|
if params['data']['event'] == 'login'
|
|
Sessions.create(client_id, session_data, { type: 'ajax' })
|
|
elsif params['data']['event']
|
|
message = Sessions::Event.run(
|
|
event: params['data']['event'],
|
|
payload: params['data'],
|
|
session: session_data,
|
|
client_id: client_id,
|
|
clients: {},
|
|
options: {},
|
|
)
|
|
if message
|
|
Sessions.send(client_id, message)
|
|
end
|
|
else
|
|
log "unknown message '#{params['data'].inspect}'", client_id
|
|
end
|
|
|
|
if new_connection
|
|
result = { client_id: client_id }
|
|
render json: result
|
|
else
|
|
render json: {}
|
|
end
|
|
end
|
|
|
|
# GET /api/v1/message_receive
|
|
def message_receive
|
|
|
|
# check client id
|
|
client_id = client_id_verify
|
|
if !client_id
|
|
render json: { error: 'Invalid client_id receive!' }, status: :unprocessable_entity
|
|
return
|
|
end
|
|
|
|
# check queue to send
|
|
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 = 3
|
|
if Rails.env.production?
|
|
count = 12
|
|
end
|
|
loop do
|
|
count = count - 1
|
|
queue = Sessions.queue(client_id)
|
|
if queue && queue[0]
|
|
logger.debug "send #{queue.inspect} to #{client_id}"
|
|
render json: queue
|
|
return
|
|
end
|
|
8.times {
|
|
sleep 0.25
|
|
}
|
|
#sleep 2
|
|
if count.zero?
|
|
render json: { event: 'pong' }
|
|
return
|
|
end
|
|
end
|
|
rescue => e
|
|
logger.error e.inspect
|
|
logger.error e.backtrace
|
|
render json: { error: 'Invalid client_id in receive loop!' }, status: :unprocessable_entity
|
|
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)
|
|
params[:client_id].to_s
|
|
end
|
|
|
|
def log( data, client_id = '-' )
|
|
logger.info "client(#{client_id}) #{data}"
|
|
end
|
|
end
|