简体   繁体   中英

AS3 unable to decode AMF3 object from socket sent by Java

I have a java socket server that sends an Animal object to the Flash client when it connects. The object is sent like this:

Amf3Output amf3Output = new Amf3Output(SerializationContext.getSerializationContext());
amf3Output.setOutputStream(userSocket.getOutputStream());
amf3Output.writeObject(animal);

And the code on flash side is:

var object:Object = socket.readObject();
trace(object);
trace(object as Animal);

However when the second trace gives me a null

I have checked that java sends out 31 bytes and Flash receives 31 bytes.

I think it might be that my Java and AS3 classes don't match some AMF requirement.

Java class:

package main;

public class Animal {

   public String name;
   public int age;
}

AS3 class:

package  
{

    [Bindable]
    [RemoteClass(alias="main.Animal")]
    public class Animal 
    {
        public var name:String;
        public var age:int;

    }

}

I'm not familiar with Java and the AMF serializers/deserializers available for it, but sending typed objects over sockets is indeed supported in flash, and works properly if you send the right data. Below is an example of a socket server in ruby communicating with a Flash application. I'm using RocketAMF to send an AMF3 object over the socket to a client after it connects.

SocketTest.as:

package {
    import flash.display.Sprite;
    import flash.net.registerClassAlias;
    import org.rackAMF.*;
    import flash.net.Socket;
    import flash.events.*;

    public class SocketTest extends Sprite {
        private var socket:Socket;

        public function SocketTest() {
            registerClassAlias('Animal', Animal);

            socket = new Socket();
            socket.addEventListener(ProgressEvent.SOCKET_DATA, onResponse);
            socket.connect("localhost", 8081);
        }

        private function onResponse(e:ProgressEvent):void {
            var animal:Animal = socket.readObject() as Animal;
            trace(Object(animal).constructor); // [trace] [class Animal]
            trace(animal.name); // [trace] Zebra
            trace(animal.age); // [trace] 5
        }
    }
}

class Animal {
    public var name:String;
    public var age:int;
}

socket_server.rb:

require 'rubygems'
require 'socket'
require 'rocketamf'

class Animal
  attr_accessor :name, :age
end

# Map "Animal" in ruby to "Animal" in flash
RocketAMF::ClassMapper.define do |m|
  m.map :as => 'Animal', :ruby => 'Animal'
end

server = TCPServer.open(8081)
loop {
  client = server.accept

  animal = Animal.new
  animal.name = "Zebra"
  animal.age = 5
  client.write RocketAMF.serialize(animal, 3)

  client.close
}

Have you checked that the objectEncoding is set to 3 on the ActionScript side? If you're sending AMF3 data and it's trying to read AMF0 data, it won't work.

Since you've taken parts of BlazeDS, it's hard to determine what are AMF3 requirements versus BlazeDS requirements. What I will say is that BlazeDS needs Java classes that follow the Java Beans spec and that means matching getters and setters.

I'm also assuming that more is needed on the Flex side to de-serialize the AMF3 payload: the on-the-wire format is not an Actionscript 3.0 object. I've done some BlazeDS custom serialization which is why I think you're missing something on the Flex side.

Is there a reason you're not using BlazeDS (or GraniteDS) for the communication?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM