【问题标题】:Red5 throws "Error loading class" when using a custom class as a SharedObject使用自定义类作为 SharedObject 时,Red5 抛出“错误加载类”
【发布时间】:2013-05-24 05:24:55
【问题描述】:

从一个 AS3 Flash 应用程序中,我尝试将 SharedObject 设置为我创建的自定义类的实例。据我所知,只要我调用sharedObject.setProperty("propertyName", myCustomClass) Red5 就会抛出“错误加载类”,然后因为解码失败而断开客户端。

似乎很多其他人都遇到过类似的问题,但我发现的一切都是关于在服务器端创建 SharedObjects。我很难找到关于在客户端(在 Flash 应用程序中)创建 SharedObject 的很多内容。我只是使用开箱即用的“实时”Red5 应用程序。

这是我在 Red5 日志中看到的实际错误...

[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 是有问题的自定义类。此类实现 IExternalizable,包括 writeExternal() 和 readExternal() 方法,以及对 registerClassAlias() 的调用。好像序列化就好了。

当然我也不必在 Red5 应用程序中重新创建此类? Red5 不应该只获取数据并在需要时将其传递给其他客户端吗?知道我错过了什么吗?

使用 Red5 1.0.1,顺便说一句。我看到很多关于 AMF3 编码的错误都在 0.7 版左右得到修复。另外,现在只是在 Windows 7 机器上进行本地测试。

【问题讨论】:

  • 查看我对这个问题的回答:stackoverflow.com/questions/15667848/…
  • 我已经打电话给registerClassAlias
  • 您需要注册每个可能在您内部引用的类Player 类(以及这些类中的任何类),您确定要这样做吗?我没有使用 Red5 的经验,所以如果问题出在那儿,其他人将不得不发表评论
  • 是的,我把它归结为一个简单的 CustomClass,它有一个用于测试的 String 属性,但也遇到了同样的问题。问题似乎与 Red5 有关,或者至少与包含的“实时”Red5 应用程序有关。

标签: actionscript-3 red5 amf shared-objects


【解决方案1】:

确保在对 SharedObject 和此类进行任何操作之前调用 registerClassAlias("com.striparcade.API.Player",com.striparcade.API.Player)。如果没问题,请确保您能够调用getDefinitionByName("com.striparcade.API.Player") 并在读取 SO 之前接收到非空值。类定义可能未编译到 SWF 中,或者包含在比您阅读 SO 的位置​​更高的帧中。

【讨论】:

  • 我已将registerClassAlias("com.striparcade.API.Player",com.striparcade.API.Player) 移至主类中构造函数的第一行。 getDefinitionByName("com.striparcade.API.Player") 在调用包含 Player 实例的 setProperty 之前返回 [class Player]。这一切看起来都是正确的,但在 Red5 日志中仍然是同样的错误。
【解决方案2】:

我已经解决了这个问题,但我不是 Red5 专家,所以如果我错了,请接受以下解释并纠正我......似乎 Red5 或“实时”应用程序包含在 Red5 中,尝试实例化它通过服务器端的 SharedObject 接收到的任何对象。因此,我相信您实际上需要在 Java 中复制您从 AS3 的客户端共享的任何 CustomClass。对我来说似乎很奇怪,但这是我能收集到的全部信息,这可以解释 Red5 错误日志。

这对我的需求是不可接受的,因为我计划让其他程序员将我的客户端代码作为 API 并抽象出服务器端细节......所以重新创建他们在服务器上提出的任何类都不是确实可行。

一个简单的解决方法是将您共享的任何内容“包装”在一个 ByteArray 中,然后在您检索它时解开它。 Red5 似乎并没有抱怨 ByteArrays,而是在不知道里面有什么的情况下愉快地将它们广播给客户端。这是我为处理这个问题而设计的几个函数......

    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;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 2019-11-16
    • 2020-02-11
    • 2021-03-06
    • 1970-01-01
    • 2013-01-15
    相关资源
    最近更新 更多