【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 响应。你可以使用以下命令与该服务交互:
- 获取服务列表
grpcurl -plaintext localhost:50051 list
- 获取服务描述
grpcurl -plaintext localhost:50051 describe myproto.MyService
- 获取方法描述
grpcurl -plaintext localhost:50051 describe myproto.MyService/MyMethod
- 调用 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 导航
编程规范
算法|面试
项目
免责声明:
本站提供的资源,都来自网络,版权争议与本站无关,所有内容及软件的文章仅限用于学习和研究目的。不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负,我们不保证内容的长久可用性,通过使用本站内容随之而来的风险与本站无关,您必须在下载后的24个小时之内,从您的电脑/手机中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。侵删请致信