PDA

View Full Version : Passing parameters to and from Red5 to Actionscript (a little confusion??)


phmenard
04-05-2010, 05:10 PM
I have a 3D multi player environment up and running quit well ... the problem I'm running into is how to send entire objects from a java coded red5 server to an actionscript client?? In my java red5 server I have a player object similar to the one below ...

public class Player extends Object{

public String name;
public String id;
public String xPos;
public String yPos;
public String zPos;
public String yRot;
public String direction;

public Player(String myName, String myId){
this.name = myName;
this.id = myId;

}

}



notice all the x,y,z Pos variables yRot and direction are all strings, Ideally I'd like them to be floats. You may by now know why this is. All players are stored in a hashmap as they come into the world.

When a player comes into the world the actionscript calls a function on the server ....


public synchronized void sendClientDetails(Object[] params) {
// send all client details

log.info("Sending client details to:-" + params[0].toString() + "Id:-"
+ params[1].toString());
IScope appScope = Red5.getConnectionLocal().getScope();

// player[0] = params[0].toString();
// player[1] = params[1].toString();

Iterator<IConnection> it = appScope.getConnections();
IConnection excluded = null;
while (it.hasNext()) {
excluded = it.next();
if (excluded.getClient().getId().equals(params[1].toString())) {
break;
// if (conn.equals(current)) {
// continue;
// }
// if (conn instanceof IServiceCapableConnection) {
// ServiceUtils.invokeOnClient(conn.getClient(), appScope,
// "createPlayer", new Object[] {player});

// }
}
}

Iterator<IConnection> it2 = appScope.getConnections();
while (it2.hasNext()) {
IConnection conn = it2.next();
if (!conn.getClient().getId().equals(excluded.getClie nt().getId())) {
// if (conn.equals(current)) {
// continue;
// }
// if (conn instanceof IServiceCapableConnection) {

Player player = playerData.get(conn.getClient().getId());

String[] playerInfo = { player.getId(), player.getName(),
player.xPos, player.yPos, player.zPos, player.yRot };


ServiceUtils.invokeOnClient(excluded.getClient(), appScope,
"createVisitor", new Object[] { playerInfo });

// }
}
}

}


notice I have to build an array out of the player abject and send it out because it seems this is the only way to get all the data back to the client ... let me explain ... in action script the data is received in this function ...


public function createVisitor(responce:Object):void {
trace(responce.xPos);
myApp.createVisitor(responce[0], responce[1], responce[2], responce[3], responce[4], responce[5]);
}




this code as well as the building of the array on the server seems so inefficient, but it works well right now. It is passed the array built from the player object . If I pass it the actual player object the only data I can seem to get is the responce.name and responce.id ... notice the trace(responce.xPos); this always returns null aswell as all the others that should be there like responce.direction. So i guess after all this my question would be how do I convert the Object[] params in the java server to responce:Object in actionscript or is it even possible ... I know it can be done using java to java but whats up with java to actionscript and vice verse because it happens sending data from actionscript to red5 as well. I hope I didn't make the question to confusing I'm sure the is someone out there that know exactlly what I'm dealing with ... thanks for all the help in advance.

sparkdemon
04-05-2010, 08:26 PM
"java coded red5 server to an actionscript client?? "

You need to use remote class directive to map custom objects in java to as3

http://livedocs.adobe.com/livecycle/es/sdkHelp/programmer/lcds/serialize_data_3.html

bowljoman
04-06-2010, 01:42 AM
Yeah, either do remote class alias or you could use an object map to get props with names.



ObjectMap<Object,Object> player=new ObjectMap<Object,Object>();

player.put("propName", propValue);
return player;

phmenard
04-06-2010, 03:07 AM
Thanks for the reply sparkdemon ... your insight sent me in the right direction. I simplified my objects by removing all functions and can now receive the object from the server and extract all data it as I said above in the AS3 script, but if I try to pass the data back to the server I get a classnotfound error ... this seems odd because I made both client and server classes exactly then same way ... any ideas?? after reading the info in the link you gave me I also found this one and followed the directions here ...

http://www.websector.de/blog/2007/09/23/best-practices-custom-class-mapping-using-openamf-and-as3-flash-cs3-not-flex/

so whats going on now??

bowljoman
04-06-2010, 04:24 AM
Your java classes also implement IExternalizable?


public class myclass implements IExternalizable {

private static final long serialVersionUID = 1222080920;

}

phmenard
04-06-2010, 11:42 AM
It does now ... but still have the same error ... ClassNotFoundException: PlayerDetails. It seems the class just doesn't exist but obviously it does.

phmenard
04-06-2010, 02:16 PM
still no luck ... I've done everything I have read about to a T ... except one thing ... I keep coming across something similar to this sentence ...

The ActionScript class to which data is converted must be used or referenced in the MXML

I have a feeling this may be the issue ... how do I go about doing this??

bowljoman
04-06-2010, 04:55 PM
Forget the other stuff you have read for a minute, and read this one which is specific to red5 and does work, if you follow it closely.

http://gregoire.org/2008/09/12/using-custom-objects-in-amf3-with-red5/

phmenard
04-06-2010, 07:52 PM
That all worked fine bowljoman thank you, but there is still an issue, following the direction you gave me I can get the object from red5 to as3 ... but I can't seem to go from as3 to red5 ... if I populate the object and send it over to red5 its always null when it gets there ... for example ...

rs.call("createPlayer", null, newPlayer);

the second parameter is null because I don't need a callback from this call all it does is tell the server that another player has joined and the server then loops through all connected clients sending back the newPlayer object to each of them so they can build the player accordingly... but as I said it always arrives null.

I really appreciate your help ... hope I'm not to much of a bother, just started with as3 and red5 ... before that all I worked with was java. Really the whole idea behind this is to be able to send and receive my own custom messages like I can do with java rather than using the array of strings I have in the working as3 version, but as I said it seems inefficient and kinda limited not to mention cumbersome to do for every call.

bowljoman
04-06-2010, 09:36 PM
You have to coordinate the read/writes of IExternalizable and target the correct class structure.

It maybe easier to convert all serializable propeties as strings. Convert all numbers to strings, etc. Then on either side of as3 and java, assume to read strings and convert to proper types using Interger.parseInt() and Float.parseFloat();

And again, you can target the wrong class in as3 as long as it parses the return as expected, but you cant target the wrong remote class in a send, even if it does have the same read/write combos on both ends.

so double check your remote alias on the client is accurate to the java package.name.Class

phmenard
04-07-2010, 01:49 AM
While I was waiting for your reply I was contemplating going back to the way I first started ... as you said assuming to read strings and convert to proper types using Interger.parseInt() and Float.parseFloat(); I just figured by building a custom object/message and sending and receiving that would some how make the whole application more efficient as far as speed, bandwidth, ect. This is easily achieved in java to java but really never new if it did make any difference ... but it did make my app easier to deal with and much more structured. So as far as as3 to java I will stick with the strings until someone tells me otherwise.

Any takers??

bowljoman I thank you for all your help and very useful links, I will continue to look into this because that's just the way I am ... I can't let it go. But I have to move on in my project so for now as far as I go I will consider this thread closed, but any and all Ideas will be much appreciated.

thallium205
05-06-2010, 04:13 AM
I, too, am having the *exact* same problem you are having. I am able to receive a created object from Red5 just fine, but I am unable to send an object to Red5 from AS3. Every time I try and pass myObject via:

nc.call("updateObjectData",null, myObject);

the resulting object parameters inside the ObjectType are all null (or zero). I have tried many things on the java end, with no avail.

//Application.java//
public void updateObjectData(Object input)
{
ObjectType temp = new ObjectType ();
temp = (ObjectType) input; // temp returns of type ObjectType but all values inside are NULL

}

I have been stuck for days on this. The only thing I have read that addresses this issue other than this thread is a user comment on this website http://gregoire.org/2008/09/12/using-custom-objects-in-amf3-with-red5/ where he stated:

TK | 12 Sep 2008 1:45 pm
Paul,
A problem I ran into a while back is serializing arrays in a custom object and sending that custom object to and from Red5. I could write the custom object on the Red5 side and send it to Flash, but I couldn’t send the custom object to Red5 from Flash. I tried casting the object returned by readObject() as multiple things, first a strict Object, next an Object[], next a Collection, then a List, then a Set… and none of it worked.
What I had to do is log out the value of the object’s getClass function. Turns out that Red5 serialized arrays serialized in custom objects as ArrayLists. Cast your readObject() result as an ArrayList and you should be fine, ie:
myList = (ArrayList) input.readObject();

– TK

Is this even applicable? Any thoughts? Did you figure it out?

bowljoman
05-08-2010, 05:06 PM
If you dont implement IExternalizable then you are dead in the water.

The short cut can be easier.


Only enumerable properties will show up. Some people create a to object function similar to 'toString'...

public function toObject():Object
{
return {"propName":this.propName, "otherPropName":this.otherpropName};
}



So in action script....



nc.call("updateObjectData",null, myObject.toObject());





In red5 use the 'ObjectMap' to handle complex unknown or changing objects.
Here are some usual casting suspects. Use the ones you need.


public void updateObjectData(ObjectMap<Object,Object> data)
{
Object obj=data.get("propName");

Object obj2=data.get("otherPropName");

String str= data.get("propName").toString();

int i = Integer.parseInt(data.get("propName").toString());

float f = Float.valueOf(data.get("propName").toString());

ArrayList<int>list =data.get("propName") ;

}