# 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.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 == 0 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