Very compact object serialization method
I'm building a realtime action multiplayer game in Flash which is using too much bandwidth because it sends message objects as XML (as required by the Smartfox server). I'm now trying to cut down on 开发者_StackOverflowthat by serializing my objects to strings before feeding them to Smartfox.
I've tried JSON but it doesn't help much. Is there another serialization method that is compacter, for example that encodes numbers in Base64 instead of decimals? I don't care about human-readability in this case.
You can give this a try. Serialize your objects to string using some method you have in place (JSON, XML, etc); then write the string to a ByteArray and compress it. The Base64 encode the compressed bytearray so you can pass it as text.
Other option could be using Flash native serializing format (AMF). This could be done too with a ByteArray, using the methods writeObject and readObject. (You should call registerClassAlias previously if you want to preserve the type information). Once you serialized your data to AMF, base64 encode the bytearray and pass it as text. Not sure if it makes sense to compress it; most likely not, since AMF is already compressed, but you could try both compressed and uncompressed and see if there's a significant difference.
Also, depending on your data, you could hand craft some kind of adhoc compression scheme that cannot be applied in the general case, but this will be more involved and will not neccesarily give the best results. I have a feeling that AMF will be a better option.
Make a serialize/de-serialize method with your own packet structure. Right now you probably have fromXML() and toXML() methods on your models -- now just add serialize() and deserialize() or toByteArray() or fromByteArray(). This will cut down massively on your size, however, there will be a lot more code -- for instance:
public class Ship {
public var x:Number;
public var y:Number;
public function toByteArray() {
var bytes:ByteArray = new ByteArray();
// packet length
// 4 bytes: length of entire packet
// 4 bytes: x float value
// 4 bytes: y float value
bytes.writeUnsignedInt(12);
bytes.writeFloat(x);
bytes.writeFloat(y);
}
public function fromByteArray(bytes:ByteArray) {
// we already know the size of our packet, so go ahead and don't read the length
var length:int = bytes.readUnsignedInt();
// read the x/y
x = bytes.readFloat();
y = bytes.readFloat();
}
}
I'm assuming you're creating big lists of items to be updated -- you might also want to only send data for items that change. Once you've created your master bytearray, you could compress it at that point, then send it over ...
Can you use Protobuf? Serialize your objects via protobuf, then send the binary data.
精彩评论