super1 发表于 2022-5-16 16:27

记录golang+cocos creator3.x + protobuf协议的坑

首先我的proto文件结构如下图


image.png

按照这样的proto文件夹结构生成对应go/js/ts 代码的话,message 相互调用是不可避免的,而golang 的导入 import和protobufjs的导入的 import是不一样的。

例如:Golang:
import "common/models/user/user.proto";
而 protobufjs 按照这样的 import 导入是找不到 user.proto文件的,所以我们需要把 import改为一个相对路径,如下
import "../user/user.proto";
再次执行 pbjs -t static-module -w commonjs -o chat.js chat.proto 就没有找不到 user.proto的错误了。

当然除此之外也可以把所有 proto文件放在一个文件夹内,用生成所有的proto 文件命令也不会报错。pbjs -t static-module -w commonjs -o all.js *.proto

以上两种方式生成完毕后还需要手动去修改几个地方才可以再cc 中使用

1.修改生成的js文件中的$protobufjs和root
原:var $protobuf = require("protobufjs/minimal");修改为:var $protobuf = protobuf;原:var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {});修改为:const $root = $protobuf.roots.creator3 || ($protobuf.roots.creator3 = $util.global);
2.如果你的proto文件中有 uint64/int64的变量时需要在ts文件导入 long
import { Long } from "protobufjs";
3.解决proto中引用问题
生成的ts源文件为:import * as $protobuf from "protobufjs";export namespace user {//省略中间代码}修改为import * as $protobuf from "protobufjs";import { Long } from "protobufjs";declare global {export namespace user {//省略中间代码}}export { user as default };
最后代码中使用
let msg = user.LoginReq.create({LoginName: username, LoginPW: password})let buffer = user.LoginReq.encode(msg).finish()let sendData = ProtocolUtils.getInstance().getDataPack(1002, buffer)NetManager.getInstance().send(sendData)
最后在将上述操作写为脚本
下面的两个shell 脚本路径是和我首图项目中的common处于同级,另外是用于mac,其他操作系统可能有些函数的不兼容,需要自己做下修改
Golang:
# shellcheck disable=SC2239#!bin/shfunction deleteGoFile(){for file in `ls $1`do   if [ -d $1"/"$file ]       then      deleteGoFile $1"/"$file   else      if [ "${file##*.}" = "go" ]          then            rm -f $1"/"$file      fi   fidone}function addGoFile(){for file in `ls $1`do   if [ -d $1"/"$file ]       then      addGoFile $1"/"$file   else      if [ "${file##*.}" = "proto" ]         then             echo $1"/"$file         protoc --go_out=. $1"/"$file      fi   fidone}deleteGoFile common/modelsaddGoFile common/models
cocos creator
# shellcheck disable=SC2239#!bin/shfunction cpDirs(){for file in `ls $1`    do    cp -r $1"/"$file "/Users/luffy/Desktop/ts_protos"done}resetProtoFileContent(){for file in `ls $1`      do      if [ -d $1"/"$file ]         then            resetProtoFileContent $1"/"$file         else            if [ "${file##*.}" = "proto" ]               then                   #注意这里是mac的sed用法                sed -i '' 's/import "common\/models/import "../g' $1"/"$file            fi      fi    done}function addJsFile(){for file in `ls $1`do   if [ -d $1"/"$file ]       then      addJsFile $1"/"$file   else      if [ "${file##*.}" = "proto" ]         then            cd $1 && pbjs -t static-module -w commonjs -o ${file%.*}".js" $file      fi   fidone}function addTsFile(){for file in `ls $1`do   if [ -d $1"/"$file ]       then      addTsFile $1"/"$file   else      if [ "${file##*.}" = "proto" ]         then            cd $1 && pbts -o ${file%.*}".d.ts" ${file%.*}".js"      fi   fidone}function resetJsFileContent() {   for file in `ls $1`      do         if [ -d $1"/"$file ]         then            resetJsFileContent $1"/"$file         else            if [ "${file##*.}" = "js" ]               then                sed -i '' 's/require("protobufjs\/minimal");/protobuf;/g' $1"/"$file                sed -i '' '10d' $1"/"$file                sed -i '' '10i\const $root = $protobuf.roots.creator3 || ($protobuf.roots.creator3 = $util.global);\' $1"/"$file                sed -i '' '$d' $1"/"$file            fi       fi      done}function resetTsFileContent() {   for file in `ls $1`      do         if [ -d $1"/"$file ]         then            resetTsFileContent $1"/"$file         else            if [ "${file##*.}" = "ts" ]               then                  sed -i '' '2i\import { Long } from "protobufjs";\\declare global {\\' $1"/"$file                  sed -i '' "\$a\\}\\\\export {${1##*/} as default};"$1'/'$file            fi       fi      done}#在桌面创建一个中间文件夹 生成js/tsrm -rf /Users/luffy/Desktop/ts_protosmkdir /Users/luffy/Desktop/ts_protoscpDirs common/modelsresetProtoFileContent /Users/luffy/Desktop/ts_protos #修改原proto文件 import 为相对路径addJsFile /Users/luffy/Desktop/ts_protosresetJsFileContent /Users/luffy/Desktop/ts_protosaddTsFile /Users/luffy/Desktop/ts_protosresetTsFileContent /Users/luffy/Desktop/ts_protos
最后将生成的ts / js文件拖入cocos creator 中就行了。
顺便说一下,这样的情况 ts 文件会报错,原因是有引用其他包message,也会在当前ts 文件中写出来。可以不用去管它,不影响项目,也可以手动或者在脚本中删除。
页: [1]
查看完整版本: 记录golang+cocos creator3.x + protobuf协议的坑