require 'hara/client_interaction' require 'celluloid' require 'socket' require 'json' module Hara module App include ClientInteraction Actions = {} class << self def included klass klass.send :include, Celluloid klass.send :include, Celluloid::Logger klass.send :finalizer, :app_finalizer klass.send :extend, ClassMethods ::Hara.const_set :Application, klass end end module ClassMethods def define_action action, &block action = action.to_s warn "Action #{action} duplication defined" if Actions.has_key? action Hara::Application.send :define_method, action, &block method = Hara::Application.send :instance_method, action Hara::Application.send :remove_method, action Actions[action] = method end end ##callback methods def after_connect end def before_action action, args end def after_action action, args end def on_close close_info = {} end ################## #like method_missing def action_missing action, args info "#{client_ip} request action: #{action} args: #{args.inspect}, action not defined" raise NoMethodError, "undefined action '#{action}' for #{self}:#{self.class}" end #below are internal functions(should not been overriding) def initialize handshake, socket socket_setup handshake, socket async.hara_setup end def hara_setup info "#{client_ip} coming" after_connect end def process_msg message action, args = Hara.decode_msg(message) info "#{client_ip} request action: #{action} args: #{args.inspect}" before_action action, *args call_action action, *args after_action action, *args rescue StandardError => e info "#{client_ip} processing error:\n#{e.inspect}" terminate end def call_action action, *args if Actions.has_key? action Actions[action].bind(self).call *args else action_missing action, *args end end def set_close_info close_info @_close_info = close_info end def app_finalizer on_close @_close_info ensure @socket.close if @socket end end end