【go】【grpc】【grpcurl】

@


写在前面

  • 相关博文
  • 个人博客首页
  • 免责声明:仅供学习交流使用!开源框架可能存在的风险和相关后果将完全由用户自行承担,本人不承担任何法律责任。

1. grpc

proto

syntax = "proto3";
package proto;
option go_package = "project"; # 生成结构体和方法的路径

service Svc {
    rpc SvcFunc (Request) returns (Response){}
}
message Request{
    int id = 1;
    string name = 2;
}
message Response {
    int code = 1;
    string msg = 2;
    repeated Data data = 3; 
}
message Data {
    string data = 1;
}

protoc

  • install
protoc --version
go get -u google.golang.org/protobuf/cmd/protoc-gen-go
  • 生成代码
protoc --go_out=. --go-gprc_out=. project/*.proto

部分代码如下

package myproto

import (
    context "context"
    grpc "google.golang.org/grpc"
    codes "google.golang.org/grpc/codes"
    status "google.golang.org/grpc/status"
)

type MyServiceServer interface {
    MyMethod(context.Context, *MyMessage) (*MyMessage, error)
    mustEmbedUnimplementedMyServiceServer()
}

type UnimplementedMyServiceServer struct {
}

func (UnimplementedMyServiceServer) MyMethod(context.Context, *MyMessage) (*MyMessage, error) {
    return nil, status.Errorf(codes.Unimplemented, "method MyMethod not implemented")
}

func (UnimplementedMyServiceServer) mustEmbedUnimplementedMyServiceServer() {}

func RegisterMyServiceServer(s grpc.ServiceRegistrar, srv MyServiceServer) {
    s.RegisterService(&_MyService_serviceDesc, srv)
}

var _MyService_serviceDesc = grpc.ServiceDesc{
    ServiceName: "myproto.MyService",
    HandlerType: (*MyServiceServer)(nil),
    Methods: []grpc.MethodDesc{
        {
            MethodName: "MyMethod",
            Handler:    _MyService_MyMethod_Handler,
        },
    },
    Streams:  []grpc.StreamDesc{},
    Metadata: "myproto.proto",
}

grpc service

  • service
package main

import (
    "context"
    "log"
    "net"

    "google.golang.org/grpc"
    pb "example.com/myproto"
)

type server struct {
    pb.UnimplementedMyServiceServer
}

func (s *server) MyMethod(ctx context.Context, in *pb.MyMessage) (*pb.MyMessage, error) {
    return &pb.MyMessage{Name: "Hello " + in.Name}, nil
}

func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterMyServiceServer(s, &server{})
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

2. grpcurl

使用 Go 安装

go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest

reflection

	"google.golang.org/grpc/reflection"
)

func main() {
	s := grpc.NewServer()
	reflection.Register(s)
}

使用 grpcurl

1. 获取服务列表

要获取一个 gRPC 服务器上的服务列表,你可以使用以下命令:

grpcurl -plaintext localhost:50051 list

这个命令会列出服务器上所有的服务。-plaintext 选项用于不使用 TLS(在开发环境中很常见)。

2. 获取服务描述

要描述一个具体的服务,你可以使用 grpcurl 的 describe 命令:

grpcurl -plaintext localhost:50051 describe myproto.MyService

3. 获取方法描述

grpcurl -plaintext localhost:50051 describe myproto.MyService/MyMethod

4. 调用 gRPC 方法

调用一个简单的 gRPC 方法并传递 JSON 格式的请求数据:

这里,-d 选项用于指定请求数据。

grpcurl -plaintext -d '{"name": "world"}' localhost:50051 myproto.MyService/MyMethod

5. 自动检测和加载 protobuf 文件

如果你没有服务的 .proto 文件,可以让 grpcurl 自动检测并加载服务的反射 API:

grpcurl -plaintext localhost:50051 list

假设有一个服务 myproto.MyService,它有一个方法 MyMethod,该方法接受一个 MyMessage 请求并返回一个 MyMessage 响应。你可以使用以下命令与该服务交互:

  1. 获取服务列表
grpcurl -plaintext localhost:50051 list
  1. 获取服务描述
grpcurl -plaintext localhost:50051 describe myproto.MyService
  1. 获取方法描述
grpcurl -plaintext localhost:50051 describe myproto.MyService/MyMethod
  1. 调用 MyMethod 方法
grpcurl -plaintext -d '{"name": "world"}' localhost:50051 myproto.MyService/MyMethod

如果一切配置正确,你应该会看到服务器返回的响应。
使用 TLS 进行安全通信

如果你的 gRPC 服务器启用了 TLS,你需要提供 CA 证书、客户端证书和私钥来建立安全连接。例如:

grpcurl -cacert ca.pem -cert client.pem -key client-key.pem localhost:50051 myproto.MyService/MyMethod

其他常用选项

-H:指定 HTTP header。例如 -H "Authorization: Bearer <token>"。
-max-time:设置最大请求时间。例如 -max-time 10 设置最大请求时间为10秒。

通过这些命令和选项,你可以使用 grpcurl 工具来与 gRPC 服务进行交互,进行测试和调试。


err too many argument

3. grpc client

package main

import (
	"context"
	"fmt"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"time"
)

func main() {
	// c, err := grpc.Dial("localhost:443", grpc.WithTransportCredentials(insecure.NewCredentials())) // 低版本 dail
	c, err := grpc.NewClient("localhost:443", grpc.WithTransportCredentials(insecure.NewCredentials())) // 高版本 newClient
	if err != nil {
		fmt.Sprintln(err)
		return
	}

	client := proto.NewTagClient(c)
	var ctx, cancel = context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	res, err := client.List(ctx, &proto.Request{Name: "NAME"})
	if err != nil {
		fmt.Sprintln(err)
		return
	}
	fmt.Println(res)

}


参考资料

基础/标准库/第三方库


golang 导航


编程规范


算法|面试


项目


posted @   Nones  阅读(76)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示