Class: FSR::Listener::Outbound

Inherits:
EventMachine::Protocols::HeaderAndContentProtocol
  • Object
show all
Includes:
App
Defined in:
lib/fsr/listener/outbound.rb

Constant Summary

SENDMSG_METHOD_DEFINITION =

Redefine the FSR::App methods to wrap sendmsg around them

[
 "def %s(*args, &block)",
 "  sendmsg super",
 " @queue.unshift(block_given? ? block : lambda {})",
 "end"
].join("\n")

Constants included from App

APPLICATIONS, LOAD_PATH, REGISTER_CODE

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Methods included from App

#applications, list, load_all, load_application, register

Instance Attribute Details

- (Object) session (readonly)

Returns the value of attribute session



10
11
12
# File 'lib/fsr/listener/outbound.rb', line 10

def session
  @session
end

Instance Method Details

- (Object) api(command, &block)

API



61
62
63
64
# File 'lib/fsr/listener/outbound.rb', line 61

def api(command, &block)
  send_data("api #{command}\r\n\r\n")
  @queue.unshift block if block_given?
end

- (Object) next_step



80
81
82
83
# File 'lib/fsr/listener/outbound.rb', line 80

def next_step
  @step += 1
  receive_reply(@session)
end

- (Object) post_init (protected)



86
87
88
89
90
91
92
# File 'lib/fsr/listener/outbound.rb', line 86

def post_init
  @read_var = nil
  @session = nil # holds the session object
  @queue = [] # Keep track of queue for state machine
  send_data("connect\n\n")
  FSR::Log.debug "Accepting connections."
end

- (Object) queue_pop (protected)



131
132
133
134
135
136
137
138
139
140
# File 'lib/fsr/listener/outbound.rb', line 131

def queue_pop
  if @queue.size > 0
    if @read_var and session.headers[@read_var.to_sym]
      r, @read_var = @read_var.to_sym, nil
      @queue.pop.call(session.headers[r])
    else
      @queue.pop.call
    end
  end
end

- (Object) receive_reply(reply)

receive_reply is called when a response is received. Overwrite this in your worker class with the call/channel handling logic you desire, taking @step into account for state management between commands

Parameters:

  • reply

    This HeaderAndContent instance will have the channel variables in #content, if the session has been updated



45
46
47
# File 'lib/fsr/listener/outbound.rb', line 45

def receive_reply(reply)
  FSR::Log.debug reply.inspect
end

- (HeaderAndContentResponse) receive_request(header, content) (protected)

receive_request is called each time data is received by the event machine


 it will manipulate the received data into either a new session or a reply,
 to be picked up by #session_initiated or #receive_reply.
 If your listener is listening for events, this will also renew your @session
 each time you receive a CHANNEL_DATA event.

Parameters:

  • header

    The header of the request, as passed by HeaderAndContentProtocol

  • content

    The content of the request, as passed by HeaderAndContentProtocol

Returns:



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/fsr/listener/outbound.rb', line 104

def receive_request(header, content)
  hash_header = headers_2_hash(header)
  if content.to_s.match(/:/)
    hash_content = headers_2_hash(content)
  else
    hash_content = content
  end
  session_header_and_content = HeaderAndContentResponse.new({:headers => hash_header, :content => hash_content})
  # If we're a new session, call session initiate
  if session.nil?
    establish_new_session(session_header_and_content)
  elsif @uuid_var  and session_header_and_content.headers[:content_type] == "api/response"
    FSR::Log.info("@uuid_var is set => #{session_header_and_content.inspect} : #{content}")
    r, @uuid_var = session_header_and_content.content.strip, nil
    @queue.pop.call(r) if @queue.size > 0
  elsif @api_request and session_header_and_content.headers[:content_type] == "api/response"
    @queue.pop.call if @queue.size > 0
  elsif session_header_and_content.content.class == Hash
    if session_header_and_content.content[:event_name] # If content includes an event_name, it must be a response from an api command
      check_for_updated_session(session_header_and_content, hash_content, hash_header)
    end
  else
    update_state_machine(session_header_and_content)
  end
end

- (Object) sched_hangup(secs, &block)

Scheduel Hangup



75
76
77
78
# File 'lib/fsr/listener/outbound.rb', line 75

def sched_hangup(secs, &block)
  send_data("api sched_hangup +#{secs} #{@session.headers[:unique_id]} alotted_timeout\n\n")
  @queue.unshift block if block_given?
end

- (Object) sendmsg(message)

sendmsg sends data to the EM app socket via #send_data, or returns the string it would send if #send_data is not defined. It expects an object which responds to either #sendmsg or #to_s, which should return a EM Outbound Event Socket formatted instruction



54
55
56
57
58
# File 'lib/fsr/listener/outbound.rb', line 54

def sendmsg(message)
  text = message.respond_to?(:sendmsg) ? message.sendmsg : message.to_s
  message = "sendmsg\n%s\n" % text
  self.respond_to?(:send_data) ? send_data(message) : message
end

- (Object) session_initiated

session_initiated is called when a @session is first created. Overwrite this in your worker class with the call/channel handling logic you desire



34
35
36
37
# File 'lib/fsr/listener/outbound.rb', line 34

def session_initiated
  FSR::Log.warn "#{self.class.name}#session_initiated not overwritten"
  FSR::Log.debug session_data.inspect
end

- (Object) update_session(&block)

Update_session



68
69
70
71
# File 'lib/fsr/listener/outbound.rb', line 68

def update_session(&block)
  send_data("api uuid_dump #{@session.headers[:unique_id]}\n\n")
  @queue.unshift block if block_given?
end