gRPC是谷歌推出的一个rpc服务框架, 数据编码采用protobuf实现.
安装环境
- go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
- go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
复制代码缺少可能导致出现可执行程序没有找到的报错, 可以参考stackoverflow的帖子
文件
- syntax = "proto3";
- option go_package = "./myproto";
- package myproto;
- message Hello {
- string name = 1;
- }
- service HelloService {
- rpc SayHello (Hello) returns (Hello);
- }
复制代码 分别需要message和service2个部分的内容
编译
- ./bin/bin/protoc --go_out=. ./myproto/hello.proto
- ./bin/bin/protoc --go-grpc_out=. ./myproto/hello.proto
复制代码使用上述指令编译为符合grpc使用的服务, 一个是message的定义的GO实现, 一个是service的定义的GO实现
根据grpc官方文档应该采用类似以下的指令实现, 效果是一样的- protoc --go_out=. --go_opt=paths=source_relative \
- --go-grpc_out=. --go-grpc_opt=paths=source_relative \
- ./myproto/hello.proto
复制代码
- 本质是编译message和编译rpc的service
使用
以下代码为生成出来的go的grpc的服务的代码- // HelloServiceClient is the client API for HelloService service.
- //
- // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
- type HelloServiceClient interface {
- SayHello(ctx context.Context, in *Hello, opts ...grpc.CallOption) (*Hello, error)
- }
- type helloServiceClient struct {
- cc grpc.ClientConnInterface
- }
- func NewHelloServiceClient(cc grpc.ClientConnInterface) HelloServiceClient {
- return &helloServiceClient{cc}
- }
- func (c *helloServiceClient) SayHello(ctx context.Context, in *Hello, opts ...grpc.CallOption) (*Hello, error) {
- cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
- out := new(Hello)
- err := c.cc.Invoke(ctx, HelloService_SayHello_FullMethodName, in, out, cOpts...)
- if err != nil {
- return nil, err
- }
- return out, nil
- }
复制代码这些是自动生成的文件内容
Server
- // HelloServiceServer is the server API for HelloService service.
- // All implementations must embed UnimplementedHelloServiceServer
- // for forward compatibility.
- type HelloServiceServer interface {
- SayHello(context.Context, *Hello) (*Hello, error)
- mustEmbedUnimplementedHelloServiceServer()
- }
复制代码以上代码是编译器自动生成的GO代码
Client
- // HelloServiceClient is the client API for HelloService service.
- //
- // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
- type HelloServiceClient interface {
- SayHello(ctx context.Context, in *Hello, opts ...grpc.CallOption) (*Hello, error)
- }
复制代码以上为自动编译生成的代码
启动服务
在自己编写的代码中使用上述生成的代码
可以参考go-grpc官方仓库样例代码
server
- package main
- import (
- "context"
- "fmt"
- "log"
- "myrpc/myproto"
- "net"
- "google.golang.org/grpc"
- )
- const (
- PORT = 1234
- )
- type Server struct {
- myproto.UnimplementedHelloServiceServer
- }
- func (s *Server) SayHello(ctx context.Context, in *myproto.Req) (*myproto.Res, error) {
- log.Printf("Received: %v", in.Name)
- return &myproto.Res{Message: "Hello " + in.Name}, nil
- }
- func main() {
- list, err := net.Listen("tcp", fmt.Sprintf(":%d", PORT))
- if err != nil {
- log.Printf("failed to listen: %v", err)
- }
- log.Printf("server listening at :%d", PORT)
- grpcServer := grpc.NewServer()
- myproto.RegisterHelloServiceServer(grpcServer, &Server{})
- grpcServer.Serve(list)
- }
复制代码整体实现和常见的rpc类似
client
- package main
- import (
- "context"
- "fmt"
- "myrpc/myproto"
- "time"
- "google.golang.org/grpc"
- "google.golang.org/grpc/credentials/insecure"
- )
- const (
- PORT = 1234
- )
- func main() {
- conn, err := grpc.NewClient(fmt.Sprintf(":%d", PORT), grpc.WithTransportCredentials(insecure.NewCredentials()))
- if err != nil {
- panic(err)
- }
- defer conn.Close()
- c := myproto.NewHelloServiceClient(conn)
- ctx, cancel := context.WithTimeout(context.Background(), time.Second)
- defer cancel()
- res, err := c.SayHello(ctx, &myproto.Req{Name: "xuhe"})
- if err != nil {
- panic(err)
- }
- fmt.Println(res.GetMessage())
- }
复制代码 FQ
常见报错- panic: grpc: no transport security set (use grpc.WithTransportCredentials(insecure.NewCredentials()) explicitly or set credentials)
- goroutine 1 [running]:
- main.main()
- /home/xuhe/tmp/go/rpc/cmd/client/main.go:18 +0x1d4
- exit status 2
复制代码 需要手动设置为conn, err := grpc.NewClient(fmt.Sprintf(":%d", PORT), grpc.WithTransportCredentials(insecure.NewCredentials()))不安全的实现方式
参考
grpc使用GO官方文档
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |