【typescript/flatbuffer】在websocket中使用flatbuffer

目录

说在前面

  • 操作系统:Windows11
  • node版本:v18.19.0
  • typescript flatbuffer版本:24.3.25

场景

  • 服务器(本文为golang+gin)与前端通信时使用flatbuffer进行序列化与反序列化
  • 通信协议为websocket

fbs

  • 测试使用的flatbuffer schema如下:

    c 复制代码
    namespace fbs;
    
    enum Command:int32 {
        None        = 0,
        Mesh        = 1,
        PhysXml     = 2,
    }
    
    table MsgWebsocket {
        cmd:    Command;
        data:   [ubyte];
    }

    相对比较简单,唯一复杂的地方在于使用了一个byte数组

  • 获取flatc

    github release页面下载对应版本的二进制程序,这里下载了windows版本的

    解压后得到flatc.exe

  • 生成golang代码

    shell 复制代码
    bin\flatc.exe -g ws.fbs 
    # bin\flatc.exe -g -o ..\ ws.fbs
    # -o 制定生成目录 
  • 生成typescript代码

    shell 复制代码
    bin\flatc.exe --ts ws.fbs 

服务器代码

  • 反序列化前端发来的数据:

    go 复制代码
    func handleFbMsg(p []byte, ws *websocket.Conn) {
    	// GetRootAsMsgWebsocket为生成的函数,用于解析二进制数据
    	msg := fbs.GetRootAsMsgWebsocket(p, 0)
    	switch msg.Cmd() {
    	case fbs.CommandMesh:
    		mesh, err := os.ReadFile("./a.bin")
    		if err == nil {
    			ws.WriteMessage(websocket.BinaryMessage, buildByteFbMsg(msg.Cmd(), mesh))
    		} else {
    			fmt.Println(err)
    		}
    	case fbs.CommandPhysXml:
    	}
    }
  • 序列化要发给前端的数据:

    go 复制代码
    func buildByteFbMsg(cmd fbs.Command, b []byte) []byte {
    	builder := flatbuffers.NewBuilder(len(b) + 4)
    
    	off := builder.CreateByteVector(b)
    	// start
    	fbs.MsgWebsocketStart(builder)
    	fbs.MsgWebsocketAddCmd(builder, cmd)
    	fbs.MsgWebsocketAddData(builder, off)
    	// end
    	end := fbs.MsgWebsocketEnd(builder)
    	builder.Finish(end)
    
    	nb := builder.FinishedBytes()
    	return nb
    }

    flatbuffer的序列化过程比较复杂,具体的例子可以参考官方文档

前端typescript代码

  • 反序列化,代码和后端类似:

    typescript 复制代码
    private handleSceneMsg(data: any) {
        var buffer = new ByteBuffer(new Uint8Array(data.data))
        var msg = MsgWebsocket.getRootAsMsgWebsocket(buffer)
        switch (msg.cmd()) {
            case Command.Mesh:
                break
            case Command.PhysXml:
                break
        }
    }
  • 序列化:

    typescript 复制代码
    public ok(cmd: Command) {
        const builder = new flatbuffers.Builder(0)
        MsgWebsocket.startMsgWebsocket(builder)
        MsgWebsocket.addCmd(builder, cmd)
        const end = MsgWebsocket.endMsgWebsocket(builder)
        builder.finish(end)
        const data = builder.asUint8Array()
        
        this._socket.send(data)
    }

问题

  • 如何序列化?
    参考官方文档,说实在的,fb的序列化是目前见过最麻烦的了,其他大部分都是一个函数搞定

  • 前端反序列化出错

    typescript 复制代码
    var buffer = new ByteBuffer(data.data)

    最开始是这行代码,data是websocket的事件,data.data实际上是arraybuffer,需要转换一下,

    typescript 复制代码
    var buffer = new ByteBuffer(new Uint8Array(data.data))
相关推荐
uuai1 小时前
echarts不同版本显示不一致问题
前端·javascript·echarts
自然 醒1 小时前
企业微信自建应用开发详细教程,如何获取授权链接?如何使用js-sdk?
javascript·vue.js·企业微信
Moonbit1 小时前
MoonBit Pearls Vol.12:初探 MoonBit 中的 Javascript 交互
javascript·后端·面试
chenbin___2 小时前
react native中 createAsyncThunk 的详细说明,及用法示例(转自通义千问)
javascript·react native·react.js
技术小丁2 小时前
使用 HTML + JavaScript 实现酒店订房日期选择器(附完整源码)
前端·javascript
hashiqimiya2 小时前
harmonyos的鸿蒙的跳转页面的部署
开发语言·前端·javascript
闭着眼睛学算法2 小时前
【双机位A卷】华为OD笔试之【排序】双机位A-银行插队【Py/Java/C++/C/JS/Go六种语言】【欧弟算法】全网注释最详细分类最全的华子OD真题题解
java·c语言·javascript·c++·python·算法·华为od
Drift_Dream2 小时前
深入浅出 requestAnimationFrame:让动画更流畅的利器
javascript
GIS瞧葩菜3 小时前
【无标题】
开发语言·前端·javascript·cesium
彭于晏爱编程3 小时前
关于表单,别做工具库舔狗
前端·javascript·面试