SFSObject和SFSArray SmartFoxServer 2X

»SFSObject和SFSArray

SmartFoxServer 2X引入了两个基本类SFSObject和SFSArray,它们是客户端和服务器之间操作和传输数据的核心。这两个类在所有语言(包括服务器端API)的所有API中是常见的,使得将代码移植到任何平台和应用程序的每一侧都非常容易。

SFSObject和SFSArray表示一个平台中立的高级对象,用于抽象客户端和服务器之间的数据传输。它们用于分别以Map / Dictionary或List / Array的形式分别表示数据;它们可以嵌套以创建复杂的数据结构,并支持许多不同的数据类型(从字节到整数,双精度,字符串和更多)。
这两个类对通过网络发送的每个数据元素提供细粒度的控制,并使用默认的SFS2X二进制协议提供高速序列化。

我们来看一下这个简单的例子:我们需要在多人游戏中发送相对于战车的数据。

ISFSObject sfso = new SFSObject();
sfso.putByte("id", 10);
sfso.putShort("health", 5000);
sfso.putIntArray("pos", Arrays.asList(120,150));
sfso.putUtfString("name", "Hurricane"); 

在代码中,我们使用单个字节(带符号的8位)发送任何小的整数值,一个Short(带符号的16位),用于较大的值和整数,用于任何应该被表示为常规(带符号)32位值的数字 。 在这个例子中,我们设想有一个广泛的RTS环境,我们使用一个Int数组来传输车辆的x / y位置。
»支持的数据类型
这是两个类支持的所有类型的列表:
这里写图片描述
当传输所有相同类型的值列表时,数组类型特别有用,结果是非常紧凑的数据结构。 另一方面,如果您需要发送不同类型的值列表,SFSObject将是最佳选择。

注意ActionScript 3开发人员
AS3阵列与这些阵列之间存在根本区别。 后者是密集数组,这意味着它们在每个索引中必须具有一个值(或至少为零),而AS3数组不具有相同的限制。
»使用示例

SFSObject / SFSArray使用的一个例子是在扩展开发中,它们被用于传输每个请求和响应。 通过扩展本文开头提供的示例,我们来看看一个完整的用例。

客户端(ActionScript 3)需要将以下数据传输到服务器扩展:

public function sendSomeData():void
{
    var sfso:SFSObject = new SFSObject();
    sfso.putByte("id", 10);
    sfso.putShort("health", 5000);
    sfso.putIntArray("pos", [120,150]);
    sfso.putUtfString("name", "Hurricane"); 

    // Send request to Zone level extension on server side
    sfs.send( new ExtensionRequest("data", sfso) );
}

服务器扩展将在其中一个请求处理程序中接收与参数对象相同的数据:

public class DataRequestHandler extends BaseClientRequestHandler
{
    @Override
    public void handleClientRequest(User sender, ISFSObject params)
    {
        // Get the client parameters
        byte id = params.getByte("id");
        short health = params.getShort("health");
        Collection<Integer> pos = params.getIntArray("pos");
        String name = params.getUtfString("name");

        // Do something cool with the data...
    }
}

»检查SFSObject / SFSArray

我们来仔细看看这两个课程,详细看看幕后发生了什么。 这两个对象都提供了两种有用的方法来以分层或十六进制转储格式转储其内容。

如果我们采用与文章开头相同的示例,并在SFSObject上调用getDump方法,我们将看到此输出:

(short) health: 5000
(utf_string) name: Hurricane
(byte) id: 10
(int_array) pos: [120, 150]

对象中的每个元素都列出如下格式:(type)key-name:value

如果你想要一个更低级别的视图,如何使用二进制表示对象,你可以调用SFSObject.getHexDump方法:

Binary size: 54
12 00 04 00 06 68 65 61 6C 74 68 03 13 88 00 04     .....health.....
6E 61 6D 65 08 00 09 48 75 72 72 69 63 61 6E 65     name...Hurricane
00 02 69 64 02 0A 00 03 70 6F 73 0C 00 02 00 00     ..id....pos.....
00 78 00 00 00 96  

»字节数组

特别提到的是ByteArray类型,它提供了将二进制数据传输到服务器的功能。这可以用于传输小文件,图像,媒体文件,加密数据等。例如,Flash开发人员可以通过套接字发送外部SWF文件来提高其应用程序的安全性,这将在间谍HTTP流量时无法检测到。

传输大量数据时,我们强烈建议您先对其进行预压缩,以优化大小,避免服务器端出现严重的压力。特别地,为了避免显着的性能下降(特别是在大的并发性)下,动态协议压缩不会引起大量数据(几十/百MB)。强烈推荐在传输之前对数据进行压缩或压缩。
»SFSObject / SFSArray最佳实践

SFSObject和SFSArray不是线程安全的,因此在多线程环境中共享这些对象时,应该特别小心。在90%的情况下,SFSObject / SFSArray仅用于数据传输并作为局部变量处理,因此不涉及并发。

如果您使用几个类来表示游戏中的模型,建议您按顺序将toSFSObject和newFromSFSObject方法添加到您的类中,以帮助将它们转换为SFSObject表示形式,并反之亦然。至少你应该通过网络更频繁地转移给那些类。

这是Java中的一个例子,我们假设我们有一个RTS游戏,其中有几种经常被更新到客户端的车辆。具体来说,我们有一个CombatQuad类(Dune II怀旧,叹息!)代表了游戏中的一个。在服务器端,我们可能至少需要使用toSFSObject方法从实例中提取相关属性,并在更新中发送它们。

public class CombatQuad
{
    private int unitID;
    private int posx;
    private int posy;
    private int energyLevel;
    private int bulletCount;

    public CombatQuad(int unitID)
    {
        this.unitID = unitID;
        this.energyLevel = 100;
        this.bulletCount = 20;
    }

    //... More getters and setters...

    public ISFSObject toSFSObject()
    {
        ISFSObject sfso = new SFSObject();

        sfso.putByte("id", unitID);
        sfso.putShort("px", posx);
        sfso.putShort("py", posy);
        sfso.putByte("el", energyLevel);
        sfso.putShort("bc", bulletCount);

        return sfso;
    }
}

我们省略了所有的getter / setters直接到点,并显示如何工作。 toSFSObject方法负责提取我们需要的属性,也可以使用最小的数据类型进行格式化。 当我们在更新时发送这些对象数据时,我们的扩展代码将大大简化:

public void sendMapUpdate(CombatQuad quad, OtherObject other, User recipient)
{
    ISFSObject responseObj = new SFSObject();
    responseObj.putSFSObject("quad", quad.toSFSObject());
    responseObj.putSFSObject("other", other.toSFSObject());

    send("quadUpdate", responseObj, recipient);
}

在客户端,我们将使用类似的,尽管相反的方法:我们将从通过SFSObject传输的属性重建类实例。 为了这样做,我们将实现一个名为newFromSFSObject的静态构造函数。

ublic class CombatQuad
{
    private var unitID:int;
    private var posx:int;
    private var posy:int;
    private var energyLevel:int;
    private var bulletCount:int;

    public static function newFromSFSObject(sfso:ISFSObject):CombatQuad
    {
        var combatQuad:CombatQuad = new CombatQuad(sfso.getByte("id"));
        combatQuad.posx = sfso.getShort("px");
        combatQuad.posy = sfso.getShort("py");
        combatQuad.energyLevel = sfso.getByte("el");
        combatQuad.bulletCount = sfso.getByte("bc");

        return combatQuad;
    }

    function CombatQuad(unitID:int):void
    {
        this.unitID = unitID;
    }

    //... More getters and setters...
}

»AS3 only:对象/数组到SFSObject / SFSArray转换

在ActionScript 3中,SFSObject和SFSArray类提供了直接转换到它们各自的本机类型:Object和Array。这是为了帮助从以前为SmartFoxServer 1.x编写的代码进行迁移,并为使用动态类型的开发人员提供了一些额外的便利。

有必要强调,通常不推荐使用通用对象而不是数据模型的类,因为它不会利用ActionScript 3中引入的类型优化。动态附加到对象的属性不是强 - 并且它们不能被编译器优化。

无论如何,这可以在几个场合有用,它可以帮助加快发展。附加的方法如下。

SFSObject.newFromObject:静态构造函数,从Object生成一个新的SFSObject实例。支持的类型有:null,Boolean,Number,String,Object,Array。该操作支持嵌套对象。
SFSObject.toObject:将SFSObject实例转换为Object,包括嵌套对象。
SFSArray.newFromArray:静态构造函数,从Array生成一个新的SFSArray实例。支持的类型有:null,Boolean,Number,String,Object,Array。该操作支持嵌套对象。
SFSArray.toArray:将SFSArray实例转换为Array,包括嵌套对象。

使用这种方法的缺点是您松动了微调数字类型的功能:所有数字将被转换为32位整数(非十进制值)或64位双精度(十进制值)。
“ 更多资源

有关如何使用SFSObject和SFSArray的更多详细信息和示例,我们强烈建议您查看SFS2X提供的示例,并查阅本网站API文档部分中的文档。另请参阅Class序列化高级教程。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值