4
votes

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;

    }

}
3
Are you using an AMF Gateway, such as LiveCycle or BlazeDS? IF so, which one. - JeffryHouser
I'm not sure what you mean by AMF Gateway but I just took the flex-messaging-core.jar and flex-messaging-common.jar from blazeDS lib folder as they are used for the encoding/decoding process. - Rob Fox
An AMF Gateway is, basically, some program you are running on the server which will translate the server side objects into client side objects and client side objects into server side objects. It also handles the routing of your RemoteObject calls. It probably does other stuff too. It sounds like you're trying to use the BlazeDS classes manually; as opposed to setting up BlazeDS as a gateway and letting it handle that. This is an unusual approach. - JeffryHouser
I am using sockets and transfer the data using socket streams. I don't see why this wouldn't work if I use BlazeDS' encoder. I also know there are other frameworks that do this. - Rob Fox
I don't know why it isn't working either. You are taking a very unusual approach to using AMF. I'm sure in the end it will give you a solid understanding of the protocol and how it is implemented, but it's beyond my knowledge to offer an answer to your question. Best of luck! - JeffryHouser

3 Answers

2
votes

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
}
0
votes

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.

0
votes

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?