Front-end and in-game use Google Protocol buffer 0, what is protobuf
Protobuf is a flexible, efficient, language-independent, structured data representation that protobuf smaller, faster, and simpler than XML. You can define your own PROTOBUF data structure, use the PROTOBUF compiler to generate language-specific source code, such as C++,java,python, and so on, the current protobuf to mainstream programming languages are supported, very convenient for serialization and deserialization.
Characteristics:
- Platform-Independent, language-independent.
- Binary, data self-description.
- Provides a complete and detailed Operation API.
- High performance 20-100 times faster than XML
- Small size 3-10 times smaller than XML scalability
- Data self-description, pre-and post compatibility
1, download the PROTOBUF compiler
Currently the latest version is protocol buffers v3.5.1
2. Configure Environment variables
Extractprotoc-3.5.1-osx-x86_64.zip
MAC configuration environment variable vi ~/.bash_profile
makes its configuration effectivesource ~/.bash_profile
#protobufexport PROTOBUF_HOME=/Users/Javen/Documents/dev/java/protobuf/protoc-3.5.1-osx-x86_64export PATH=$PATH:$PROTOBUF_HOME/bin
Window adds the bin to the path, for example:D:\protobuf\protoc-3.5.1-win32\bin
本文在Mac环境下编写
The only difference between Mac and the window command is that it needs to be changed to the protoc
protoc.exe
premise that the environment variable needs to be added.
3. Write a proto file
File saved as chat.proto
this proto
file excerpt from T-io to make it easy to develop network programming
syntax = "proto3";package com.im.common.packets;option java_package = "com.im.common.packets"; //设置java对应的packageoption java_multiple_files = true; //建议设置为true,这样会每个对象放在一个文件中,否则所有对象都在一个java文件中/** * 聊天类型 */enum ChatType { CHAT_TYPE_UNKNOW = 0;//未知 CHAT_TYPE_PUBLIC = 1;//公聊 CHAT_TYPE_PRIVATE = 2;//私聊}/** * 聊天请求 */message ChatReqBody { int64 time = 1;//消息发送时间 ChatType type = 2; //聊天类型 string text = 3; //聊天内容 string group = 4; //目标组id int32 toId = 5; //目标用户id, string toNick = 6; //目标用户nick}/** * 聊天响应 */message ChatRespBody { int64 time = 1;//消息发送时间 ChatType type = 2; //聊天类型 string text = 3; //聊天内容 int32 fromId = 4; //发送聊天消息的用户id string fromNick = 5; //发送聊天消息的用户nick int32 toId = 6; //目标用户id string toNick = 7; //目标用户nick string group = 8; //目标组id}
4, the compiler compiles it 4.1 compiles to Java
Go to the project with the directory to execute the following compilation name, com/im/common/packets
for chat.proto
the package name in, and the chat.proto
file to be placed com/im/common/packets
under.
protoc --java_out=./ com/im/common/packets/chat.proto
4.2 Compile to JS
protoc --js_out=import_style=commonjs,binary:. chat.proto
After execution, the file is generated in the current folder chat_pb.js
, which is protobuf
the API and some functions. If you Node.js
can use it directly, you protobuf
need to do some processing if you want to use it in the browser (front end).
5. Front-end Use PROTOBUF process steps 5.1 NPM installation required libraries
chat_pb.js
Install the Reference library in the file's sibling directory
npm install -g requirenpm install google-protobufnpm install -g browserify
5.2 Compiling and packaging files using browserify
Write script to save as Exports.js
var chatProto = require('./chat_pb'); module.exports = { DataProto: chatProto }
Execute command browserify exports.js > chat.js
chat_pb.js
after compiling and packaging the files, chat.js
you can use them happily.
6. Protobuf using Protobuf in Example 6.1 front-end (JavaScript)
<script src="./chat.js"></script><script type="text/javascript"> var chatReqBody = new proto.com.im.common.packets.ChatReqBody(); chatReqBody.setTime(new Date().getTime()); chatReqBody.setText("测试"); chatReqBody.setType(1); chatReqBody.setGroup("Javen"); chatReqBody.setToid(666); chatReqBody.setTonick("Javen205"); var bytes = chatReqBody.serializeBinary(); console.log("序列化为字节:"+bytes); var data = proto.com.im.common.packets.ChatReqBody.deserializeBinary(bytes); console.log("反序列化为对象:"+data); console.log("从对象中获取指定属性:"+data.getTonick()); console.log("对象转化为JSON:"+JSON.stringify(data)); </script>
6.2 Using Protobuf in Java
In Java to use PROTOBUF,PROTOBUF and JSON to convert each other, the first need to introduce the relevant Jar,maven POM coordinates are as follows
<dependency> <groupId>com.google.protobuf</groupId> <artifactId> Protobuf-java</artifactid> <version>3.5.1</version></dependency><dependency> < Groupid>com.googlecode.protobuf-java-format</groupid> <artifactid>protobuf-java-format</ Artifactid> <version>1.4</version></dependency>
public static void Test () {try {Jsonformat Jsonformat = new Jsonformat (); Chatrespbody.builder Builder = Chatrespbody.newbuilder (); Builder.settype (Chattype.chat_type_public); Builder.settext ("Javen test"); Builder.setfromid (1); Builder.setfromnick ("Javen"); Builder.settoid (110); Builder.settonick ("Javen.zhou"); Builder.setgroup ("Javen"); Builder.settime (Systemtimer.currenttimemillis ()); Chatrespbody chatrespbody = Builder.build (); From Protobuf to json String Asjson = jsonformat.printtostring (chatrespbody); System.out.println ("Object to JSON" +asjson); byte[] Bodybyte = Chatrespbody.tobytearray (); Decoding is converted from byte[] to Java object chatrespbody parsechatrespbody = Chatrespbody.parsefrom (bodybyte); Asjson = jsonformat.printtostring (parsechatrespbody); System.out.println ("Bodybyte To JSON "+asjson"); Transfer from JSON to protobuf chatrespbody.builder _builder = Chatrespbody.newbuilder (); Jsonformat.merge (New Bytearrayinputstream (Asjson.getbytes ()), _builder); Chatrespbody _chatrespbody = _builder.build (); Asjson = jsonformat.printtostring (_chatrespbody); SYSTEM.OUT.PRINTLN ("JSON to Protobuf" +asjson); } catch (Exception e) {e.printstacktrace (); } }
6.3 QQ play a play in the use of PROTOBUF
chat.js
change the revision in to var global = Function('return this')();
// var global = Function('return this')();var global = (function(){ return this;})()
Bk. Script.loadlib (' gameres://qqplaycore.js '); Bk. Script.loadlib (' gameres://tio/chat.js '); function test () {var ws = new BK. WebSocket ("Ws://127.0.0.1:9326?group=test&name=javen"); Ws.onopen = function (ws) {BK. Script.log (1, 0, "onopen.js"); Bk. Script.log (1, 0, "1.readyState =" + ws.getreadystate ()); var time = 0; Bk. Director.ticker.add (Function (ts, duration) {time = time + 1; if (time% = = 0) {//Ws.send ("Phone test" + time); var chatreqbody = new Proto.com.im.common.packets.ChatReqBody (); Chatreqbody.settime (New Date (). GetTime ()); Chatreqbody.settext ("Phone test" + time); Chatreqbody.settype (1); Chatreqbody.setgroup ("test"); var bytes = Chatreqbody.serializebinary (); Ws.send (bytes); } }); }; Ws.onclose = function (ws) {BK. Script.log (1, 0, "onclose.js"); Bk. Script.loG (1, 0, "1.readyState =" + ws.getreadystate ()); }; Ws.onerror = function (ws) {BK. Script.log (1, 0, "onerror.js"); Bk. Script.log (1, 0, "1.readyState =" + ws.getreadystate ()); Bk. Script.log ("OnError.js.js geterrorcode:" + ws.geterrorcode ()); Bk. Script.log ("Onerror.js geterrorstring:" + ws.geterrorstring ()); }; Ws.onmessage = function (ws, event) {if (!event.isbinary) {var str = event.data.readAsString (); Bk. Script.log (1, 0, "text =" + str); } else {var buf = Event.data; Resets the cursor pointer to 0 buf.rewind (); var ab = new ArrayBuffer (buf.length); var dv = new DataView (AB); while (!buf.eof) {dv.setuint8 (Buf.pointer, Buf.readuint8buffer ()); } var chatrespbody = Proto.com.im.common.packets.ChatRespBody.deserializeBinary (AB); var msg = Chatrespbody.getfromnick () + "say:" + chatrespbody.gettext ();Bk. Script.log (1, 0, "text =" + msg); } }; Ws.onsendcomplete = function (ws) {BK. Script.log (1, 0, "onsendcomplete.js"); }; Ws.connect ();} Test ();
6.4 Eget using the Protobuf plugin download
Egret provides proto文件
tools that will generate JS and TS
npm install protobufjs -gnpm install @egret/protobuf -g
Operation Steps
1. Create a new folder in the root directory of the Egret project protobuf
, and then protobuf
create a new folder in the folder protofile
2. proto
put the files protofile
in the folder
3, sequential execution pb-egret add
,pb-egret generate
The following actions will be done automatically:
1. In tsconfig.json
the node in the include
addprotobuf/**/*.d.ts
2. egretProperties.json
modules
Add the nodes in
{"name": "protobuf-library","path": "protobuf/library"},{"name": "protobuf-bundles","path": "protobuf/bundles"}
3, protobuf
automatically generated in the folder bundles
and the library
folder contains the JS we need and TS
Can be used in projects
Processing send messages
private sendReq(text:string,group:string){ var chatReqBody = new com.im.common.packets.ChatReqBody(); chatReqBody.time = new Date().getTime(); chatReqBody.text = text; chatReqBody.type = com.im.common.packets.ChatType.CHAT_TYPE_PUBLIC; chatReqBody.group = group; let data = com.im.common.packets.ChatReqBody.encode(chatReqBody).finish(); this.sendBytesData(data); } private sendBytesData(data:Uint8Array){ this.socket.writeBytes(new egret.ByteArray(data)); }
Processing receive messages
private onReceiveMessage(e:egret.Event):void { //创建 ByteArray 对象 var byte:egret.ByteArray = new egret.ByteArray(); //读取数据 this.socket.readBytes(byte); let buffer = new Uint8Array(byte.buffer); let chatRespBody = com.im.common.packets.ChatRespBody.decode(buffer); // this.trace("收到数据:"+JSON.stringify(chatRespBody)); this.trace(chatRespBody.fromNick+" 说: "+chatRespBody.text); }
6.5 Cocos Creator in use Protobuf
Cocos Creator using the protobuf in the front end with the protobuf operation step is basically the same , just in Cocos creator need to import JS as a plug- in
Import JS compiled in 5.2 into the project's script folder, open Cocos Creator will prompt you if you want to set the script as a plug-in.
Can be used in projects
Same as used in 6.1 frontend.
start: function () { cc.log("start"); let chatReqBody = new proto.com.im.common.packets.ChatReqBody(); chatReqBody.setTime(new Date().getTime()); chatReqBody.setText("测试"); chatReqBody.setType(1); chatReqBody.setGroup("Javen"); chatReqBody.setToid(666); chatReqBody.setTonick("Javen205"); let bytes = chatReqBody.serializeBinary(); cc.log("序列化为字节:" + bytes); let data = proto.com.im.common.packets.ChatReqBody.deserializeBinary(bytes); cc.log("反序列化为对象:" + data); cc.log("从对象中获取指定属性:" + data.getTonick()); cc.log("对象转化为JSON:" + JSON.stringify(data)); },
How to use protobuf here is finished, personal ability is limited if there is a mistake to welcome correct. You have better solutions or suggestions welcome to exchange discussions, if you have questions welcome message.