protobuf is a general rule of data serialization, which is faster and smaller than xml and json.
This time, proto 3 is used. 3 has some features different from 2. For example, 3 defaults to the optional declaration.
All fields are optional assignments, so as to be compatible with the fact that some fields will be discarded in a specific version. When serializing, no fields will be converted.
Use of caretor js
After writing the proto file, you can use protoc to compile it. When the creator JS references google-protobuf.js, there will be problems. After solving the problem, I decide to use protobufjs. It is better to use protobufjs with npm environment to download and install. The installation of nodejs and npm is not covered here.
- Install protobufjs
-g is the global installation. After installation, find the directory and configure it. /protobufjs/bin environment variable. There are two executable files pbjs and pbts in bin directory, which are used to compile proto files. Using protobufjs will not use protoc.
# npm install -g protobufjs
- Compiling proto files
// game.proto syntax = "proto3" message Login { string username = 1; string password = 2; int32 uid = 3; } message LoginResult { string token = 1; }
After configuring environment variables, compile proto file with pbjs
# pbjs -t json-module game.proto > client.json
# pbjs -t static-module game.proto > clientProto.js
-t [params] | Parameter description |
---|---|
json | JSON representation |
json-module | JSON representation as a module |
proto2 | Protocol Buffers, Version 2 |
proto3 | Protocol Buffers, Version 3 |
static | Static code without reflection (non-functional on its own) |
static-module | Static code without reflection as a module |
Note: different parameters export different file types.
- Use in js
// proto.js const proto = require("clientProto") module.exports = { // static-module proto: function(name, pwd) { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readystatus = 4 && xhr.status >= 200 && xhr.status < 300) { var b = stringToBytes(xhr.responseText); //Here we need to convert the string to a byte array proto.LoginResult.decode(b); } } xhr.open("POST", "localhost:8080/login"); m_xhr.setRequestHeader("Content-Type","application/x-protobuf"); m_xhr.setRequestHeader("Accept","application/x-protobuf"); if (m_xhr.overrideMimeType){ //This is required. Otherwise, a string is returned, causing protobuf decoding error. //For details, please refer to http://www.ruanyifeng.com/blog/2012/09/xmlhttprequest'level'2.html. m_xhr.overrideMimeType("text/plain; charset=x-user-defined"); } var param = proto.Login.encode({username:name, password:pwd).finish(); xhr.send(param); }, // json module. The json file is not used. It will be completed after use. proto2: function() { } };
Use of golang
If go is used, I use iris framework. Here is an example of how iris can be parsed.
package main import ( "gameProto" "github.com/golang/protobuf/proto" "github.com/kataras/iris" ) func main() { app := iris.New() app.Post("/login", loginHandler) app.Run(iris.Addr("0.0.0.0:8080")) } func ProtoUnmashal(data []byte, v interface{}) error { return proto.Unmashal(data, v.(proto.Message)) // proto analysis method } func loginHandler(c iris.Context) { login := &gameProto.Login{} // This is the parsed go structure // Resolve the parameters passed by the client if c.UnmarshalBody(login, iris.UnmarshalerFunc(ProtoUnmashal)); err != nil { return } // do something ... loginResult := &gameProto.LoginResult{} loginResult.Token = "zx7g9f8h79j80sh98af766" if b, err := proto.Mashal(loginResult); err != nil { return } else { c.Write(b) } }