Use Google Protocol buffer in front-end and in-game

Source: Internet
Author: User
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.jsInstall 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.jsafter 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.jschange 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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.