FlatBuffers在JavaScript中的使用笔记
在使用flatbuffers工作之前,你首先需要创建一个schema文件。这个schema文件定义了所有你想序列化的数据结构。
1.创建schema文件xone.fbs。
1 namespace xone.genflat; 2 3 table LoginRequest{ 4 msgID:int=1; 5 username:string; 6 password:string; 7 } 8 9 table LoginResponse{ 10 msgID:int=2; 11 uid:string; 12 } 13 14 15 16 //root_type非必须。 17 18 //root_type LoginRequest; 19 //root_type LoginResponse;
在你写完schema文件后,下一步是使用flatc编译它。(创建flat编译的方法见 "创建flatc,FlatBuffer的编译器"。)
2.编译写好的schema文件。
执行命令: flatc -s xone.fbs 会生成对应的xone_generated.js文件。
schema文件里所有定义的table,struct,union 在编译后的generated.js文件中都会有对应的操作方法。例如GetRootAsTabelName,etc。
3.创建 FlatBuffers
第一步是引入对应的库文件还有刚刚编译后的xone_generated.js文件。
1 var flatbuffers = require('/js/flatbuffers').flatbuffers; 2 var xone = require('./xone_generated').xone; //Generated by `flatc`.
现在已经可以在程序中创建一些buffers了。我们首先需要创建一个FlatBufferBuilder的实例builder,之后都是对这个builder进行操作。
var builder = new flatbuffers.Builder(1); var username = builder.createString("zlh"); var password = builder.createString("xxx"); xone.genflat.LoginRequest.startLoginRequest(builder) xone.genflat.LoginRequest.addUsername(builder,username) xone.genflat.LoginRequest.addPassword(builder,password) xone.genflat.LoginRequest.addMsgID(builder,5) var req = xone.genflat.LoginRequest.endLoginRequest(builder) builder.finish(req) //创建结束时记得调用这个finish方法。
4.通过WebSocket发送创建好的buffers。
因为websocket只支持ArrayBuffer和String。所以要将生成后的buffers转化为ArrayBuffer再通过webSocket发送。
//builder有对应的asUint8Array方法可以将内容转为ArrayBuffer。 NetManager.sendMessage(builder.asUint8Array())
因为网络发送一般还需要有一个消息ID,所以可以进行一下操作。
var buf = builder.dataBuffer() //我们暂且将msgId约定为两个字节 var temp1 = new ArrayBuffer(buf.bytes().length + 2) var newbuf = new Uint8Array(temp1) //假设msgid为257,将msgid转为2个字节的byte数组 var mId = this.intTobyte2(257) //将msgid放到buf的头两个字节字节中 newbuf.set([b[0],b[1]],0) //将之前生成的buffer追加到后边 newbuf.set(builder.asUint8Array(),2) //通过网络发送出去 NetManager.sendMessage(newbuf.buffer)
这样后端服务器在接收到消息后,就可以进行拆分。取出头两个字节作为msgId,根据msgId做对应的处理。例如收到257时表示前段传过来的是LoginRequest请求,则将buffer[2:]内容作为LoginRequest进行解析。
从网络收到buffer后:
receiveMessage:function(message){ //转为可操作的buffer(ArrayBuffer不可直接操作,不需通过视图操作) var buf = new Uint8Array(message) //取出前两个字节并进行解析 var msgId = new Uint8Array(message,0,2) var id = this.byte2Toint(msgId) console.log('msgId:'+id) //假设收到的msgId为257 则取出之后的buffer按照LoginResponse进行解析 var data = new Uint8Array(message,2,buf.length-2) var b = new flatbuffers.ByteBuffer(data) //这步不要忘记 var loginRes = xone.genflat.LoginResponse.getRootAsLoginResponse(b) console.log("msgID:"+loginRes.msgID()); console.log("uid:"+loginRes.uid()); }