Colyseus 0.10:引入了新的状态序列化算法

我真的很高兴宣布Colyseus的0.10版本。 此版本基本上引入了性能更高的状态序列化算法和在客户端解码状态的不同方法。 目前可用于JavaScript,Defold Engine和Unity3D。

新的序列化器( @ colyseus / schema )不仅优化了应用程序的吞吐量,而且还优化了服务器端和客户端的内存和CPU消耗。 请参阅使用Colyseus的先前和新串行器传输的字节数之间的比较。

通过严格定义状态中每个属性的数据类型,这是可能的。 只有带有“ @type ”注解的类型才会被同步。 不再需要使用“ @nosync ”不可同步的属性。

以前的序列化器有什么问题?

除了易于使用之外,以前的串行器在编码和解码大型状态对象时都有一些缺点。

  • 即使没有进行任何更改,服务器也需要在每个补丁程序中获取状态快照,以便能够检查先前的状态快照是否不同于当前的状态快照。 然后,将补丁程序作为它们之间的二进制差异进行广播。
  • 为了在客户端应用更改,补丁是在服务器发送的最后一个快照之上应用的-这意味着需要再次反序列化整个状态,为每个补丁创建一个新的状态副本,并且会降低性能如果您的状态稍大。

好消息是,新的串行器解决了这两个问题。

新的序列化器-服务器端

在下面的状态定义中,您将看到Player实例的映射。

 从“ @ colyseus / schema”导入{Schema,MapSchema,type}; 

class Player扩展了架构{
@type(“ number”)
宽度:数字;

@type(“ number”)
高度:数字;
}

类MyState扩展架构{
@type({map:Player})
玩家=新的MapSchema ();
}

现在,让我们在房间处理程序中实例化状态:

 从“ colyseus”导入{Room}; 
从“ ./MyState”导入{MyState};
  class MyRoom扩展了房间{ 
onInit(){
this.setState(new MyState());
}
}

在客户端,成功加入会议室后,状态便可用。 您可以通过将回调直接注册到已解码的状态变量中来侦听添加,删除和更改。

新的序列化器-客户端(JavaScript)

侦听客户端更改的方式取决于您感兴趣的结构。容器中的变量更改可通过“ onChange ”回调获得:

  var client = new Colyseus.Client(“ ws:// localhost:2567”); 
var room = client.join(“ my_room”);
  room.onJoin.add(()=> { 
room.state.onChange =(更改)=> {
changes.forEach(change => {
console.log(change.field);
console.log(change.value);
console.log(change.previousValue);
});
};
})

可以通过容器变量中的“ onAdd ”和“ onRemove ”回调来添加和删除数组和映射上的条目。

  room.state.players.onAdd =(玩家,键)=> { 
console.log(播放器,“已添加到”,键);
};
  room.state.players.onRemove =(玩家,键)=> { 
console.log(播放器,“已被删除”,键);
};

对于Array和Map中的子实体,您可以检测到整个对象或特定变量的变化:

  //回调整个对象 
//无法知道哪些属性已更改
room.state.players.onChange =(玩家,键)=> {
console.log(播放器,“已更改为”,键);
};
  //回调以检查特定的属性更改 
//通过这种方式,您确切地知道哪些属性已更改
room.state.players.onAdd =(玩家,键)=> {
player.onChange =函数(更改){
changes.forEach(change => {
console.log(change.field);
console.log(change.value);
console.log(change.previousValue);
});
}
};

请参阅此处的从版本0.9到0.10的迁移指南。

就是0.10

我强烈建议您升级到0.10版,即使您不打算使用新的序列化器也是如此。 以前的序列化器仍然可用,并且不会在不久的将来被弃用。