探秘Proto文件:解析定义与参数揭秘

2023-10-15 18:43:26 浏览数 (1)

前言:apply bct又涉及到了serviceproto,不太懂,学习一下~ 在这立个flag年底就去考网络工程师证书or嵌入式工程师证书

代码语言:javascript复制
NOTICE  2023-09-26 10:56:46.336009 0800: Stopping tcpdump since packet capture is not required by the remaining tests

NOTICE  2023-09-26 10:56:46.336774 0800: Terminating BCT.
*** Beginning Network Interoperability Test ***
Please enter the device's service type in the form 
	"_<service>._<proto>.local.", e.g. "_printer._tcp.local."
	(or try again with "-M"):

Proto文件是Google开发的一种用于定义数据结构和服务接口的语言,通常用于在不同平台之间进行数据交换和通信。

Proto文件由消息(message)、服务(service)和枚举(enum)三个主要组件构成。

消息(message)是定义数据结构的主要方式,类似于面向对象编程中的类。可以在消息中定义字段(field),指定字段的类型和名称,还可以添加注释等元数据。

服务(service)定义了一组可供远程调用的方法(method)。每个方法都有输入和输出参数,可以在服务中定义多个方法。

枚举(enum)定义了一组具名的整数常量,可以作为消息字段的取值范围或者服务方法的选项。

除了上述基本组件外,Proto文件还支持import语句用于导入其他Proto文件,可以实现模块化和复用。

Proto文件使用简洁的语法来定义数据结构和接口,同时还支持扩展、自定义选项等高级特性,使得它非常适合用于跨平台的数据交换和通信场景。

需要注意的是,Proto文件只是一种定义语言,并不直接对应具体的实现代码,需要使用相应的编译器或工具将Proto文件转换为目标平台的具体代码。


优化Proto文件定义及参数说明

一、Proto文件命名规范: 包名.服务名.proto

二、Proto语法关键字:

  • syntax:协议类型,目前有两套协议proto3和proto2,推荐使用proto3,必须放在Proto文件的第一行。
  • package:包名,必须放在第二行。
  • service:定义Proto文件中的方法集合,类似于方法接口。
  • message:定义消息结构,类似于Go语言的结构体,在其中定义方法的接收和返回参数。
  • returns:定义返回响应,与service一起使用。
  • rpc:定义方法,与service一起使用。

变量类型:

  • optional:与message一起使用,表示该字段为可选项,可以传也可以不传。
  • repeated:与message一起使用,表示该字段接收或返回为数组。

三、示例:

代码语言:javascript复制
syntax = "proto3";
package user;

service HelloService {
  rpc SayHello (HelloRequest) returns (HelloResponse){}
}

message HelloRequest {}

message HelloResponse {
  string msg = 1;
}

编译命令:

代码语言:javascript复制
protoc --go_out=plugins=grpc:. server.hello.proto

服务端示例:

代码语言:javascript复制
package main

import (
	"flag"
	"fmt"
	"log"
	"net"

	user "grpc.zozoo.net/protos"
	"grpc.zozoo.net/impl"
	"google.golang.org/grpc"
)

func main() {
	flag.Parse()
	lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 9000))
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}

	log.Println("端口监听成功:9000")

	grpcServer := grpc.NewServer()
	user.RegisterHelloServiceServer(grpcServer, &impl.HelloService{})
	grpcServer.Serve(lis)
}

客户端示例:

代码语言:javascript复制
package main

import (
	"context"
	"log"

	"google.golang.org/grpc"

	user "grpc.zozoo.net/protos"
)

func main() {
	conn, err := grpc.Dial(":9000", grpc.WithInsecure())
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}

	// 调用RPC方法
	hello := user.NewHelloServiceClient(conn)
	rsp, err := hello.SayHello(context.TODO(), &user.HelloRequest{})
	if err != nil {
		log.Fatalf("方法调用失败 err  %v", err)
	}

	log.Println(rsp.Msg)
	defer conn.Close()
}

0 人点赞