I am trying to create a custom object in AS3 to pass information to and from a server, which in this case will be Red5. In the below screenshots you will see that I am able to send a request for an object from as3, and receive it successfully from the java server. However, when I try to cast the received object to my defined objectType using 'as', it takes the value of null. It is my understanding that that when using "as" you're checking to see if your variable is a member of the specified data type. If the variable is not, then null will be returned.
This screenshot illustrates that I am have successfully received my object 'o' from red5 and I am just about to cast it to the (supposedly) identical datatype testObject of LobbyData:
EnlargeHowever, when testObject = o as LobbyData;
runs, it returns null. :(
Below you will see my specifications both on the java server and the as3 client. I am confident that both objects are identical in every way, but for some reason flash does not think so. I have been pulling my hair out for a long time, does anyone have any thoughts?
AS3 Object:
import flash.utils.IDataInput;
import flash.utils.IDataOutput;
import flash.utils.IExternalizable;
import flash.net.registerClassAlias;
[Bindable]
[RemoteClass(alias = "myLobbyData.LobbyData")]
public class LobbyData implements IExternalizable
{
private var sent:int; // java sentinel
private var u:String; // red5 username
private var sen:int; // another sentinel?
private var ui:int; // fb uid
private var fn:String; // fb name
private var pic:String; // fb pic
private var inb:Boolean; // is in the table?
private var t:int; // table number
private var s:int; // seat number
public function setSent(sent:int):void
{
this.sent = sent;
}
public function getSent():int
{
return sent;
}
public function setU(u:String):void
{
this.u = u;
}
public function getU():String
{
return u;
}
pub开发者_JAVA百科lic function setSen(sen:int):void
{
this.sen = sen;
}
public function getSen():int
{
return sen;
}
public function setUi(ui:int):void
{
this.ui = ui;
}
public function getUi():int
{
return ui;
}
public function setFn(fn:String):void
{
this.fn = fn;
}
public function getFn():String
{
return fn;
}
public function setPic(pic:String):void
{
this.pic = pic;
}
public function getPic():String
{
return pic;
}
public function setInb(inb:Boolean):void
{
this.inb = inb;
}
public function getInb():Boolean
{
return inb;
}
public function setT(t:int):void
{
this.t = t;
}
public function getT():int
{
return t;
}
public function setS(s:int):void
{
this.s = s;
}
public function getS():int
{
return s;
}
public function readExternal(input:IDataInput):void
{
sent = input.readInt();
u = input.readUTF();
sen = input.readInt();
ui = input.readInt();
fn = input.readUTF();
pic = input.readUTF();
inb = input.readBoolean();
t = input.readInt();
s = input.readInt();
}
public function writeExternal(output:IDataOutput):void
{
output.writeInt(sent);
output.writeUTF(u);
output.writeInt(sen);
output.writeInt(ui);
output.writeUTF(fn);
output.writeUTF(pic);
output.writeBoolean(inb);
output.writeInt(t);
output.writeInt(s);
}
}
Java Object:
package myLobbyData;
import org.red5.io.amf3.IDataInput;
import org.red5.io.amf3.IDataOutput;
import org.red5.io.amf3.IExternalizable;
public class LobbyData implements IExternalizable
{
private static final long serialVersionUID = 115280920;
private int sent; // java sentinel
private String u; // red5 username
private int sen; // another sentinel?
private int ui; // fb uid
private String fn; // fb name
private String pic; // fb pic
private Boolean inb; // is in the table?
private int t; // table number
private int s; // seat number
public void setSent(int sent)
{
this.sent = sent;
}
public int getSent()
{
return sent;
}
public void setU(String u)
{
this.u = u;
}
public String getU()
{
return u;
}
public void setSen(int sen)
{
this.sen = sen;
}
public int getSen()
{
return sen;
}
public void setUi(int ui)
{
this.ui = ui;
}
public int getUi()
{
return ui;
}
public void setFn(String fn)
{
this.fn = fn;
}
public String getFn()
{
return fn;
}
public void setPic(String pic)
{
this.pic = pic;
}
public String getPic()
{
return pic;
}
public void setInb(Boolean inb)
{
this.inb = inb;
}
public Boolean getInb()
{
return inb;
}
public void setT(int t)
{
this.t = t;
}
public int getT()
{
return t;
}
public void setS(int s)
{
this.s = s;
}
public int getS()
{
return s;
}
@Override
public void readExternal(IDataInput input)
{
sent = input.readInt();
u = input.readUTF();
sen = input.readInt();
ui = input.readInt();
fn = input.readUTF();
pic = input.readUTF();
inb = input.readBoolean();
t = input.readInt();
s = input.readInt();
}
@Override
public void writeExternal(IDataOutput output)
{
output.writeInt(sent);
output.writeUTF(u);
output.writeInt(sen);
output.writeInt(ui);
output.writeUTF(fn);
output.writeUTF(pic);
output.writeBoolean(inb);
output.writeInt(t);
output.writeInt(s);
}
}
AS3 Client:
public function refreshRoom(event:Event)
{
var resp:Responder=new Responder(handleResp,null);
ncLobby.call("getLobbyData", resp, null);
}
public function handleResp(o:Object):void
{
var testObject:LobbyData=new LobbyData;
testObject = o as LobbyData;
trace(testObject);
}
Java Client
public LobbyData getLobbyData(String param)
{
LobbyData lobbyData1 = new LobbyData();
lobbyData1.setSent(5);
lobbyData1.setU("lawlcats");
lobbyData1.setSen(5);
lobbyData1.setUi(5);
lobbyData1.setFn("lulz");
lobbyData1.setPic("lulzagain");
lobbyData1.setInb(true);
lobbyData1.setT(5);
lobbyData1.setS(5);
return lobbyData1;
}
As you already figured out, you should use registerClassAlias as the RemoteClass works out of the box only for Flex projects (as bindable, etc).
Be sure to call registerClassAlias before any serializing / deserializing occurs.
Also, the debugger is showing you the actual tipe of your "o" parameter, which is object. This shows that the player is not correctly mapping the AMF serialized object's class to any of your classes (so, by default, it goes with Object). You should see a LobbyData object in the debugger; otherwise, no matter how you cast / coerce it, it won't work.
The objet needs to be declared before the responder is called.
public function refreshRoom(event:Event)
{
var testObject:LobbyData=new LobbyData;
var resp:Responder=new Responder(handleResp,null);
ncLobby.call("getLobbyData", resp, null);
}
public function handleResp(o:Object):void
{
testObject = o as LobbyData;
trace(testObject);
}
Actually if you want to workaround the type casting you can simply add this to your constructor:
public function dataAwareObject(o:* = null) { //TODO: implement function super(); if(o){ for(var a:* in o) this[a] = o[a]; } } }
Works like a charm.
精彩评论