Class: RocketAMF::Envelope
- Inherits:
-
Object
- Object
- RocketAMF::Envelope
- Includes:
- RocketAMF::Ext::Envelope, Pure::Envelope
- Defined in:
- lib/rocketamf/ext.rb,
lib/rocketamf/pure.rb,
lib/rocketamf/remoting.rb
Overview
Container for the AMF request/response.
Instance Attribute Summary collapse
-
#amf_version ⇒ Object
readonly
Returns the value of attribute amf_version.
-
#headers ⇒ Object
readonly
Returns the value of attribute headers.
-
#messages ⇒ Object
readonly
Returns the value of attribute messages.
Instance Method Summary collapse
-
#call(target, *args) ⇒ Object
Creates the appropriate message and adds it to
messages
to call the given target using the standard (old) remoting APIs. -
#call_flex(target, *args) ⇒ Object
Creates the appropriate message and adds it to
messages
using the new flex (RemoteObject) remoting APIs. -
#constructed? ⇒ Boolean
Whether or not the response has been constructed.
-
#dispatch_call(p) ⇒ Object
:nodoc:.
-
#each_method_call(request, &block) ⇒ Object
Builds response from the request, iterating over each method call and using the return value as the method call’s return value.
-
#initialize(props = {}) ⇒ Envelope
constructor
A new instance of Envelope.
-
#populate_from_stream(stream, class_mapper = nil) ⇒ Object
Populates the envelope from the given stream or string using the given class mapper, or creates a new one.
-
#result ⇒ Object
Returns the result of a response envelope, or an array of results if there are multiple action call messages.
-
#serialize(class_mapper = nil) ⇒ Object
Serializes the envelope to a string using the given class mapper, or creates a new one, and returns the result – Implemented in pure/remoting.rb RocketAMF::Pure::Envelope.
-
#to_s ⇒ Object
Return the serialized envelope as a string.
Methods included from Pure::WriteIOHelpers
#byte_order, #byte_order_little?, #pack_double, #pack_int16_network, #pack_int8, #pack_integer, #pack_word32_network
Methods included from Pure::ReadIOHelpers
#byte_order, #byte_order_little?, #read_double, #read_int16_network, #read_int8, #read_word16_network, #read_word32_network, #read_word8
Constructor Details
#initialize(props = {}) ⇒ Envelope
Returns a new instance of Envelope.
6 7 8 9 10 |
# File 'lib/rocketamf/remoting.rb', line 6 def initialize props={} @amf_version = props[:amf_version] || 0 @headers = props[:headers] || {} @messages = props[:messages] || [] end |
Instance Attribute Details
#amf_version ⇒ Object (readonly)
Returns the value of attribute amf_version.
4 5 6 |
# File 'lib/rocketamf/remoting.rb', line 4 def amf_version @amf_version end |
#headers ⇒ Object (readonly)
Returns the value of attribute headers.
4 5 6 |
# File 'lib/rocketamf/remoting.rb', line 4 def headers @headers end |
#messages ⇒ Object (readonly)
Returns the value of attribute messages.
4 5 6 |
# File 'lib/rocketamf/remoting.rb', line 4 def @messages end |
Instance Method Details
#call(target, *args) ⇒ Object
Creates the appropriate message and adds it to messages
to call the given target using the standard (old) remoting APIs. You can call multiple targets in the same request, unlike with the flex remotings APIs.
Example:
req = RocketAMF::Envelope.new
req.call 'test', "arg_1", ["args", "args"]
req.call 'Controller.action'
33 34 35 36 37 38 39 |
# File 'lib/rocketamf/remoting.rb', line 33 def call target, *args raise "Cannot use different call types" unless @call_type.nil? || @call_type == :simple @call_type = :simple msg_num = .length+1 @messages << RocketAMF::Message.new(target, "/#{msg_num}", args) end |
#call_flex(target, *args) ⇒ Object
Creates the appropriate message and adds it to messages
using the new flex (RemoteObject) remoting APIs. You can only make one flex remoting call per envelope, and the AMF version must be set to 3.
Example:
req = RocketAMF::Envelope.new :amf_version => 3
req.call_flex 'Controller.action', "arg_1", ["args", "args"]
49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/rocketamf/remoting.rb', line 49 def call_flex target, *args raise "Can only call one flex target per request" if @call_type == :flex raise "Cannot use different call types" if @call_type == :simple raise "Cannot use flex remoting calls with AMF0" if @amf_version != 3 @call_type = :flex flex_msg = RocketAMF::Values::RemotingMessage.new target_parts = target.split(".") flex_msg.operation = target_parts.pop # Use pop so that a missing source is possible without issues flex_msg.source = target_parts.pop flex_msg.body = args @messages << RocketAMF::Message.new('null', '/2', flex_msg) # /2 because it always sends a command message before end |
#constructed? ⇒ Boolean
Whether or not the response has been constructed. Can be used to prevent serialization when no processing has taken place.
156 157 158 |
# File 'lib/rocketamf/remoting.rb', line 156 def constructed? @constructed end |
#dispatch_call(p) ⇒ Object
:nodoc:
165 166 167 168 169 170 171 172 |
# File 'lib/rocketamf/remoting.rb', line 165 def dispatch_call p #:nodoc: begin p[:block].call(p[:method], p[:args]) rescue Exception => e # Create ErrorMessage object using the source message as the base Values::ErrorMessage.new(p[:source], e) end end |
#each_method_call(request, &block) ⇒ Object
Builds response from the request, iterating over each method call and using the return value as the method call’s return value. Marks as envelope as constructed after running. – Iterate over all the sent messages. If they’re somthing we can handle, like a command message, then simply add the response message ourselves. If it’s a method call, then call the block with the method and args, catching errors for handling. Then create the appropriate response message using the return value of the block as the return value for the method call.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/rocketamf/remoting.rb', line 80 def each_method_call request, &block raise 'Response already constructed' if @constructed # Set version from response # Can't just copy version because FMS sends version as 1 @amf_version = request.amf_version == 3 ? 3 : 0 request..each do |m| # What's the request body? case m.data when Values::CommandMessage # Pings should be responded to with an AcknowledgeMessage built using the ping # Everything else is unsupported command_msg = m.data if command_msg.operation == Values::CommandMessage::CLIENT_PING_OPERATION response_value = Values::AcknowledgeMessage.new(command_msg) else e = Exception.new("CommandMessage #{command_msg.operation} not implemented") e.set_backtrace ["RocketAMF::Envelope each_method_call"] response_value = Values::ErrorMessage.new(command_msg, e) end when Values::RemotingMessage # Using RemoteObject style message calls remoting_msg = m.data acknowledge_msg = Values::AcknowledgeMessage.new(remoting_msg) method_base = remoting_msg.source.to_s.empty? ? '' : remoting_msg.source+'.' body = dispatch_call :method => method_base+remoting_msg.operation, :args => remoting_msg.body, :source => remoting_msg, :block => block # Response should be the bare ErrorMessage if there was an error if body.is_a?(Values::ErrorMessage) response_value = body else acknowledge_msg.body = body response_value = acknowledge_msg end else # Standard response message response_value = dispatch_call :method => m.target_uri, :args => m.data, :source => m, :block => block end target_uri = m.response_uri target_uri += response_value.is_a?(Values::ErrorMessage) ? '/onStatus' : '/onResult' @messages << ::RocketAMF::Message.new(target_uri, '', response_value) end @constructed = true end |
#populate_from_stream(stream, class_mapper = nil) ⇒ Object
20 21 22 |
# File 'lib/rocketamf/remoting.rb', line 20 def populate_from_stream stream, class_mapper=nil raise AMFError, 'Must load "rocketamf/pure"' end |
#result ⇒ Object
Returns the result of a response envelope, or an array of results if there are multiple action call messages. It automatically unwraps flex-style RemoteObject response messages, where the response result is inside a RocketAMF::Values::AcknowledgeMessage.
Example:
req = RocketAMF::Envelope.new
req.call('TestController.test', 'first_arg', 'second_arg')
res = RocketAMF::Envelope.new
res.each_method_call req do |method, args|
['a', 'b']
end
res.result #=> ['a', 'b']
142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/rocketamf/remoting.rb', line 142 def result results = [] .each do |msg| if msg.data.is_a?(Values::AcknowledgeMessage) results << msg.data.body else results << msg.data end end results.length > 1 ? results : results[0] end |
#serialize(class_mapper = nil) ⇒ Object
Serializes the envelope to a string using the given class mapper, or creates a new one, and returns the result – Implemented in pure/remoting.rb RocketAMF::Pure::Envelope
67 68 69 |
# File 'lib/rocketamf/remoting.rb', line 67 def serialize class_mapper=nil raise AMFError, 'Must load "rocketamf/pure"' end |
#to_s ⇒ Object
Return the serialized envelope as a string
161 162 163 |
# File 'lib/rocketamf/remoting.rb', line 161 def to_s serialize end |