golang/protobuf 学习
看到k8s源码里面用到这个东西,感觉和json很相似 学习一下protobuf 和json差不多 用于 encoding/decoding 数据 github 地址是github.com/golang/protobuf开始不知道protoc这个二进制执行文件是干啥的,摸索了好一会儿才明白,原来是用于将proto文件编译为对应的程序文件按照github的例子1.创建proto文
·
看到k8s源码里面用到这个东西,感觉和json很相似 学习一下
protobuf 和json差不多 用于 encoding/decoding 数据 github 地址是github.com/golang/protobuf
开始不知道protoc这个二进制执行文件是干啥的,摸索了好一会儿才明白,原来是用于将proto文件编译为对应的程序文件
按照github的例子
1.创建proto文件,实际上就是定义数据结构
package example;
enum FOO { X = 17; };
message Test {
required string label = 1;
optional int32 type = 2 [default=77];
repeated int64 reps = 3;
optional group OptionalGroup = 4 {
required string RequiredField = 5;
}
}
2.通过protoc.exte对.proto进行编码,这里生成了test.pb.go
3.可以编写自己的程序对生成的test.pb.go进行调用
package main
import (
"fmt"
"github.com/golang/protobuf/proto"
"log"
pb "test/example"
)
func main() {
//Test对象
test := &pb.Test{
Label: proto.String("hello"),
Type: proto.Int32(17),
Reps: []int64{1, 2, 3},
Optionalgroup: &pb.Test_OptionalGroup{
RequiredField: proto.String("good bye"),
},
}
//编码
data, err := proto.Marshal(test)
if err != nil {
log.Fatal("marshaling error: ", err)
}
newTest := &pb.Test{}
//解码
err = proto.Unmarshal(data, newTest)
if err != nil {
log.Fatal("unmarshaling error: ", err)
}
// Now test and newTest contain the same data.
if test.GetLabel() != newTest.GetLabel() {
log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
}
// 查看解码内容
fmt.Println(string(newTest.String()))
}
4.protobuf对grpc的支持
test.proto
syntax = "proto3";
package example;
// 定义接口
service Calculate {
// 加法
rpc Sum (Request) returns (Reply) {}
//除法
rpc Divide (Request) returns (Reply) {}
}
// 发送两个数字
message Request {
int32 num1 = 1;
int32 num2 = 2;
}
// 返回一个数字
message Reply {
int32 num1 = 1;
}
进行编译
protoc --go_out=plugins=grpc:. *.proto
服务端代码:
package main
import (
"errors"
"golang.org/x/net/context"
"google.golang.org/grpc"
"log"
"net"
pb "test/example"
)
type server struct{}
// 加法运算
func (s *server) Sum(ctx context.Context, in *pb.Request) (*pb.Reply, error) {
return &pb.Reply{Num1: in.Num1 + in.Num2}, nil
}
// 除法运算
func (s *server) Divide(ctx context.Context, in *pb.Request) (*pb.Reply, error) {
// 判断非0
if in.Num2 == 0 {
return nil, errors.New("divide by zero")
}
return &pb.Reply{Num1: in.Num1 / in.Num2}, nil
}
func main() {
conn, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatal("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterCalculateServer(s, &server{})
s.Serve(conn)
}
客户端代码:
package main
import (
"fmt"
"golang.org/x/net/context"
"google.golang.org/grpc"
"log"
pb "test/example"
)
func main() {
conn, err := grpc.Dial("localhost:8080", grpc.WithInsecure())
if err != nil {
log.Fatal("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewCalculateClient(conn)
num1 := int32(10)
num2 := int32(1)
// num2 := int32(0)
//加法运算
r, _ := c.Sum(context.Background(), &pb.Request{num1, num2})
fmt.Printf("%d\n", r.Num1)
// 除法运算
r, err = c.Divide(context.Background(), &pb.Request{num1, num2})
if err != nil {
log.Fatal(err)
}
fmt.Printf("%d\n", r.Num1)
}
更多推荐
已为社区贡献28条内容
所有评论(0)