【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))
相关推荐
学渣y7 分钟前
React状态管理-对state进行保留和重置
javascript·react.js·ecmascript
_龙衣26 分钟前
将 swagger 接口导入 apifox 查看及调试
前端·javascript·css·vue.js·css3
struggle20252 小时前
continue通过我们的开源 IDE 扩展和模型、规则、提示、文档和其他构建块中心,创建、共享和使用自定义 AI 代码助手
javascript·ide·python·typescript·开源
x-cmd2 小时前
[250512] Node.js 24 发布:ClangCL 构建,升级 V8 引擎、集成 npm 11
前端·javascript·windows·npm·node.js
夏之小星星2 小时前
el-tree结合checkbox实现数据回显
前端·javascript·vue.js
Bl_a_ck3 小时前
【React】Craco 简介
开发语言·前端·react.js·typescript·前端框架
为美好的生活献上中指4 小时前
java每日精进 5.11【WebSocket】
java·javascript·css·网络·sql·websocket·网络协议
拖孩5 小时前
【Nova UI】十五、打造组件库之滚动条组件(上):滚动条组件的起步与进阶
前端·javascript·css·vue.js·ui组件库
苹果电脑的鑫鑫5 小时前
element中表格文字剧中可以使用的属性
javascript·vue.js·elementui
一丝晨光6 小时前
数值溢出保护?数值溢出应该是多少?Swift如何让整数计算溢出不抛出异常?类型最大值和最小值?
java·javascript·c++·rust·go·c·swift