cocos creator中使用protobuf(dcodeIO/protobuf.js 5.0)
cocos creator專案需要使用protobuf作為序列化!
查詢資料發現:
主要存在兩個解決方案 使用protobufjs 或者 谷歌官方的js解析(通過protoc.exe生成.proto對應的js檔案直接使用),個人認為protojs更為方便,如果更改.proto檔案都要使用protoc重新生成對應的js檔案略為繁瑣。所以這裡我們直接採用的protobufjs。
但是通過github使用最新的protobufjs(6.x,x版本),在require("protobuf")時,編輯器報錯 "moudule not found”,使用;參考下方資料解決:
總結就是:
需要使用之前的protobuf5.0版本(下載地址:forum.cocos.com/uploads/default/original/2X/0/0e90b3823e4520d0afa40f114b6a830ae1126c7f.zip
需要注意的是:
.proto檔案需要放在工程目錄的 assert/resources目錄下(沒有則建立)否則無法通過cc.loader.loadRes函式讀取到該檔案。
測試如下:
proto檔案:
//登陸資料
message Login{
// 命令
required string cmd = 1;
// 暱稱
required string name = 2;
// 密碼
required string pw = 3;
}
新建一個簡單地helloworld的creator檔案即可,在onLoad()函式中新增如下程式碼:
執行輸出結果如下:cc.loader.loadRes("login", function(err, msg){ cc.log("start load file"); if (err) { cc.error(err.message || err); return; } cc.log(msg); let Build = ProtoBuf.loadProto(msg); if(Build){ let LoginModule = Build.build("Login"); if(LoginModule){ let loginModule = new LoginModule(); loginModule.set("cmd", "login"); loginModule.set("name", "saint"); loginModule.set("pw", "123456"); let array = loginModule.toArrayBuffer(); let message = LoginModule.decode(array); console.log(message.get("cmd")); console.log(message.get("name")); console.log(message.get("pw")); console.log("解析後接收到的的資料為:"); console.log(message); }else{ console.log("LoginModule is null"); } }else{ console.log("Build Faild!"); } })
Simulator: start load file Simulator: message Login{ Simulator: // 命令 Simulator: required string cmd = 1; Simulator: // 暱稱 Simulator: required string name = 2; Simulator: // 密碼 Simulator: required string pw = 3; Simulator: } Simulator: login Simulator: saint Simulator: 123456 Simulator: 解析後接收到的的資料為: Simulator: .Login
正確的序列化和反序列化結果。
同時需要指出的是 cocos creator 採用的是websocket !
websocket也是基於tcp的,相當於在tcp基礎上封裝了一層。 某種程度來說tcp的效能優於websocket,因為websocket就是在tcp的基礎上多了一層轉化,但是websocket使用更簡單,用tcp的app端需要自己去讀tcp流,根據包頭和包體組裝資料包,而websocket不需要,因為websocket會是一個整包的資料並不是流的形式。 具體來說,後端通過快取區把資料沖刷(flush)給前端,app端拿到tcp資料流,需要根據訊息頭給定的訊息體長度,去拿取後面多少位的資料,然後組裝成一個數據包。 而websocket傳輸過來就是一個個的包,也就是幀並不是資料流,所以後端在給websocket資料的時候,必須要把一個整包,在緩衝區一次性沖刷過來,而給tcp的話就可以自由沖刷。
也就是說如果服務端同樣採用的是websocket的話(Node.js及 ws庫),我們對訊息是不需要新增資料頭進行資料包的組裝的。websocket是按照包一次性讀取的。既我們不需要在手動的定義資料包頭以及新增資料包長度資訊。