Protobuf使用--go和C#

时间:2024-03-12 14:39:34

一、Go安装及使用protobuf工具

以下都是基于Linux系统;

1.安装

A) protobuf 编译工具安装

1、下载 protoBuf:

cd $GOPATH/src/
git clone https://github.com/protocolbuffers/protobuf.git

2、或者直接将压缩包拖入后解压

unzip protobuf.zip 

3、安装依赖库

sudo apt-get install autoconf  automake  libtool curl make  g++  unzip libffi-dev -y

4、进入目录

cd protobuf/ 

5、自动生成configure配置文件:

./autogen.sh 

6、配置环境:

./configure

7、编译源代码(时间比较长):

make 

8、安装

sudo make install

9、刷新共享库 (很重要的一步啊)

sudo ldconfig

10、成功后需要使用命令测试

protoc -h  
B) protobuf 的 go 语言插件安装

由于protobuf并没直接支持go语言需要我们手动安装相关插件

  1. 获取 proto包(Go语言的proto API接口)
go get  -v -u github.com/golang/protobuf/proto
go get  -v -u github.com/golang/protobuf/protoc-gen-go

​ 2.编译

cd $GOPATH/src/github.com/golang/protobuf/protoc-gen-go/
go build

​ 3.将生成的 protoc-gen-go可执行文件,放在/bin目录下

sudo cp protoc-gen-go /bin/

tips:上面第2步报错,由于go install可以直接安装protobuf了,跟错误提示安装;

go install google.golang.org/protobuf@latest

2.使用

pb语法就不介绍了;

.proto文件:

syntax="proto3";                //Proto协议
package pb;                     //当前包名
option csharp_namespace="Pb";   //给C#提供的选项
option go_package = "./";		//输出路径

message BroadCast{
    int32 PID =1;
    int32 Tp = 2;
    oneof Data{
        string Content = 3;        
    }
}

直接执行以下命令,该文件夹下.proto文件都会被编译成go文件;

protoc --go_out=.  *.proto

Tips:我这里生成的go文件包名都是__,知道哪里出了错,手动改一下就完了;

具体使用方法:

package main

import (
	"fmt"
	"gameserver/pb"

	"google.golang.org/protobuf/proto"
)

func main() {
	data := &pb.BroadCast{
		PID: 1,
		Tp:  2,
		Data: &pb.BroadCast_Content{
			Content: "hello protobuf!perilla",
		},
	}
	//序列化
	binaryData, err := proto.Marshal(data)
	if err != nil {
		fmt.Println("marshal err:", err)
	}

	newdata := &pb.BroadCast{}
    //反序列化
	err = proto.Unmarshal(binaryData, newdata)
	if err != nil {
        fmt.Println("unmarshal err:",err)
	}

	fmt.Println(newdata)
}

二、C#使用protobuf工具

C#就不用geogle的protobuf了,用geogle另一个protobuf-net;

下载地址

工程有重复dll,只留一个unity文件中的dll;

类加[ProtoBuf.ProtoContract]特性,类中字段 [ProtoBuf.ProtoMember(1)];

[ProtoBuf.ProtoContract]
public class Porperties
{
    [ProtoBuf.ProtoMember(1)]
    public int id;
    [ProtoBuf.ProtoMember(2)]
    public string name;
    [ProtoBuf.ProtoMember(3)]
    public List<int> attributes;
  
    public void Init(int id, string name, List<int> attributes)
    {         
        this.id = id;          
        this.name = name;          
        this.attributes = attributes;
    }
}

void Start()
{
    Porperties p = new Porperties();
    int[] arr = { 1, 33, 44, 63 };

    p.Init(1, "perilla", new List<int>(arr));
    using (FileStream stream = File.OpenWrite("test.dat"))
    {
        //序列化
        ProtoBuf.Serializer.Serialize<Porperties>(stream, p);
    }

    Porperties p2 = new Porperties();

    using (FileStream stream = File.OpenRead("test.dat"))
    {
        //从文件中读取数据并反序列化
        p2 = ProtoBuf.Serializer.Deserialize<Porperties>(stream);
    }
    Debug.Log(string.Format(p2.name,p2.id,p2.attributes[2]));
}