I'm learning about Flash (AMF) and Java (BlazeDS) using the project I found on the internet, but I noticed that the server is receiving via socket the data below:
When I tried to use the Amf0Input/Amf3Input me to return the object, I get an error that does not recognize this type of package. Anyone know which library should I use to decode this message?
The packet you got seems to be a length prefixed AMF3 AmfObject.
In general, whenever you see a string that follows the usual naming convention of fully qualified class names (i.e. like reverse domains), chances are you're dealing with an object
instance1.
Looking at the first few bytes, you see 0x00
repeated three times. If we assume AMF3, this would be 3 undefined
s, followed by an object with type marker 0x3e
- which does not exist. If we instead assume AMF0, we would first have a number (0x00
type marker, followed by 8 bytes of data), followed by an object with type marker 0x6d
- which again does not exist.
Thus, the data you got there can't be AMF payload alone. However, if we interpret the first 4 bytes as network byte order (i.e. big endian) integer, we get 0x3E = 62
- which is exactly the length of the remaining data.
Assuming then that the first 4 bytes are just a length prefix, the next byte must be a type marker. In AMF3, 0x0a
indicates an object
instance. So lets just try to decode the remaining data (section 3.12 of the AMF3 spec, if you want to follow along2): the next byte must indicate the object traits. 0x23
means we have a direct encoding of the traits in that byte - as opposed to a reference to earlier submitted traits.
Since the fourth bit (counted from least significant first) is 0, the object is not dynamic - as in, an instance of some class, not just a plain object instance. The remaining bits, shifted to the right by 4, indicate the number of sealed properties this instance has, which is 2.
Next, we expect the classname, encoded as UTF-8-vr
- i.e. length prefixed (when shifted right by 1), UTF-8 encoded string. The next byte is 0x1d
, which means the length is 0x1d >> 1 = 14
. The next 14 bytes encode common.net.APC
, so that's the instance's class name.
Afterwards, we have the two sealed property names, also encoded as UTF-8-vr
. The first one has a prefix of 0x15
, so a length of 10 - giving us parameters
, followed by a prefix of 0x19
(length 12) and payload functionName
.
After this, you have the values corresponding to these sealed properties, in the same order. The first one has a type marker of 0x09
, which corresponds to an array. The length marker is 0x03
, which means the array contains one element, and the next byte is 0x01
, indicating we have no associative members. The only element itself has a type marker of 0x04
, meaning it's an integer
- in this case with value 0.
This is followed by a type marker of 0x06
- a string, with length 14. That string - you probably have guessed it by now - is syncServerTime
.
So, in summary, your packet is a length-prefixed instance of common.net.APC
, with it's parameters
attribute set to [0]
, and the functionName
attribute set to "syncServerTime"
.
1: The only other alternatives are a vector of object instances - which would require a type marker of 0x10
somewhere - or an AMF0 packet. In the case of an AMF0 packet, you'd also have to have a URI-style path somewhere in the packet, which is not the case here.
2: Note that the EBNF given at the end of the section is not exactly correct - neither syntactically nor semantically ...