Question

From an AS3 Flash app, I'm trying to set a SharedObject to an instance of a custom class I've created. From what I can tell, as soon as I call sharedObject.setProperty("propertyName", myCustomClass) Red5 throws "Error loading class" and then disconnects the client because decoding failed.

It seems that plenty of other people have had similar problems, but everything I've found is about creating SharedObjects on the server-side. I'm having trouble finding much about creating the SharedObject on the client-side (in the Flash app). I'm just using the included "live" Red5 app out of the box.

Here's the actual error I see in the Red5 logs...

[ERROR] [NioProcessor-7] org.red5.io.amf.Input - Error loading class: com.striparcade.API.Player
[ERROR] [NioProcessor-7] org.red5.server.net.rtmp.codec.RTMPProtocolDecoder - Error decoding buffer

com.striparcade.API.Player is the custom class in question. This class implements IExternalizable, includes writeExternal() and readExternal() methods, and a call to registerClassAlias(). It seems to serialize just fine.

Surely I don't have to recreate this class in the Red5 app as well? Shouldn't Red5 just take the data and pass it along to the other clients when needed? Any idea what I'm missing?

Using Red5 1.0.1, btw. I see that a lot of bugs regarding AMF3 encoding were fixed around version .7. Also, just testing locally on a Windows 7 machine right now.

Was it helpful?

Solution 2

I've solved the problem, but I'm no Red5 expert so take the following explanation with a grain of salt and correct me if I'm wrong... It seems that either Red5, or the "live" application included with Red5, attempts to instantiate whatever objects it receives via a SharedObject on the server-side. So, I believe you would actually need to replicate in Java whatever CustomClasses you're sharing from the client-side in AS3. Seems really odd to me, but that's all I can gather, and that would explain the Red5 error logs.

This was unacceptable for my needs, as I plan to have other programmers take my client-side code as an API and abstract away the server-side details... so recreating whatever classes they come up with on the server isn't really feasible.

An easy workaround is to "wrap" whatever you're sharing in a ByteArray and then unwrap it when you retrieve it. Red5 doesn't seem to complain about ByteArrays, and happily broadcasts them out to the client with no knowledge of what's inside. Here are a couple functions I whipped up to handle this...

    private function setRed5Property(propertyName:String, data:Object):void
    {
        var dataBytes:ByteArray = new ByteArray();
        dataBytes.writeObject(data);

        _red5SharedObject.setProperty(propertyName, dataBytes);
        _red5SharedObject.setDirty(propertyName);
    }

    private function getRed5Property(propertyName:String):Object
    {
        var dataBytes:ByteArray = new ByteArray();
        dataBytes.writeBytes(_red5SharedObject.data[propertyName]);
        dataBytes.position = 0;

        return dataBytes.readObject() as Object;
    }

OTHER TIPS

Make sure you call registerClassAlias("com.striparcade.API.Player",com.striparcade.API.Player) before you do anything with SharedObject and this class. If it's OK, make sure you are able to call getDefinitionByName("com.striparcade.API.Player") and receive a non-null value right prior to reading a SO. It's possible that the class definition is either not compiled into the SWF, or it's included on later frames than where you read the SO.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top