module GameServer::BaseListner

Базовый модуль для прослушивания JSON запросов от клиента

Constants

MAX_INPUT_BUFFER_SIZE

Attributes

input_buffer[RW]

В этом буфере хранится начало сообщения от клиента, если оно вдруг разбилось на несколько кусоков данных

process_semaphore[RW]

send_data_semaphore -семафор (mutex) для доступа к коннекшену. если не установлен - то не используется. может устанавливаться в приложении connection.send_data_semaphore = Mutex.new process_semaphore - семафор для обработки

send_data_semaphore[RW]

send_data_semaphore -семафор (mutex) для доступа к коннекшену. если не установлен - то не используется. может устанавливаться в приложении connection.send_data_semaphore = Mutex.new process_semaphore - семафор для обработки

Public Class Methods

new(*args) click to toggle source
Calls superclass method
# File lib/base_listner.rb, line 14
def initialize(*args)
  super(*args)
  self.input_buffer = ""
  self.process_semaphore = Mutex.new
end

Public Instance Methods

connection_info() click to toggle source
# File lib/base_listner.rb, line 37
def connection_info
  "CONNECTION"
end
critical_error(e) click to toggle source
# File lib/base_listner.rb, line 62
  def critical_error(e)
    log_exception e
    send_error(e.class.to_s.underscore)
#    close_connection_after_writing
  end
find_controller(request) click to toggle source
# File lib/base_listner.rb, line 20
def find_controller(request)
  return unless request.name =~ /^[A-Za-z_]+$/
  controller_name = (controllers_classes_root + "::" + request.name.camelize)
  log controller_name
  controller_name.constantize
rescue NameError
  return
end
policy_file_request(data) click to toggle source
# File lib/base_listner.rb, line 120
def policy_file_request(data)
  if data =~ /^<policy-file-request/
    send_data(File.open(Rails.root + 'config/crossdomain.xml' + "\000").read)
    #close_connection_after_writing
    return true
  end
  return false
end
process_query(query_string) click to toggle source

Обработать один запрос

# File lib/base_listner.rb, line 104
def process_query(query_string)
  request = GameServer::RequestParser.new(query_string).parse
  controller = find_controller(request)
  return send_error('unknown_request', request.name) unless controller
  controller.new(self, request, GameServer::ObjectSpace.instance).run
rescue GameServer::RequestParser::ParserError
  send_error('bad_syntax')
rescue GameServer::ServerError => e
  send_error("server_error", "#{e.name} #{!(e.comment.empty?) ? ':' + e.comment : ''}")
rescue GameError => e
  send_error(e.class.to_s.underscore, e.message)
rescue => e
  critical_error(e)
end
process_whole_message(message) click to toggle source
# File lib/base_listner.rb, line 97
def process_whole_message(message)
  message.split("\n").each do |query_string|
    process_semaphore.synchronize{ process_query(query_string) }
  end
end
receive_data(data) click to toggle source

Обработать входящие данные (может быть несклько строк запросов в одном пакете данных)

# File lib/base_listner.rb, line 73
def receive_data(data)
  data.gsub!("\000", "")

  complete_message = input_buffer + data
  if complete_message[-1] != "\n"
    self.input_buffer = complete_message
    if input_buffer.size >= MAX_INPUT_BUFFER_SIZE
      self.input_buffer.clear
      raise "OVERFLOW OF INPUT BUFFER #{input_buffer.size}"
    end
    return
  else
    input_buffer.clear
  end

  log "Received from #{connection_info} (size #{complete_message.size}): " + complete_message.inspect
  return if policy_file_request(complete_message)
  operation = proc { process_whole_message(complete_message) }
  callback = proc { nil }
  EventMachine.defer(operation, callback)
rescue => e
  critical_error(e)
end
send_data(data) click to toggle source
Calls superclass method
# File lib/base_listner.rb, line 51
def send_data(data)
  log "Data sended to #{connection_info}: " + data#.inspect

  if send_data_semaphore
    send_data_semaphore.synchronize { super(data) }
  else
    super(data)
  end
end
send_error(name, comment = "") click to toggle source
# File lib/base_listner.rb, line 29
def send_error(name, comment = "")
  send_line(['error', name, comment].to_json )
end
send_json(object) click to toggle source
# File lib/base_listner.rb, line 42
def send_json(object)
  #send_line '<?xml version="1.0" encoding="UTF-8"?>' + "\n<message>\n" + object.to_json + "\n</message>\n\000"
  send_line object.to_json
end
send_json_with_marker(marker, object) click to toggle source
# File lib/base_listner.rb, line 47
def send_json_with_marker(marker, object)
  send_json [marker, object]
end
send_line(string) click to toggle source
# File lib/base_listner.rb, line 33
def send_line(string)
  send_data(string + "\000\n" )
end