grpc入门

112 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

编写一个简单的grpc代码

目录结构

image-20221123144007373.png

编写proto文件

syntax = "proto3";
package script;
option go_package = "./;rpc";
​
message Empty{
​
}
​
message HelloResponse{
  string hello = 1;
}
​
message RegisterRequest{
  string name = 1;
  string password = 2;
}
​
message RegisterResponse{
  string uid = 1;
}
​
service Server{
  rpc Hello(Empty) returns(HelloResponse);
  rpc Register(RegisterRequest) returns(RegisterResponse);
}

syntax = "proto3";为protobuf版本

option go_package = "./;rpc";分号前为proto文件生成go文件的目录,分号后为proto文件生成go文件的包名

protoc --go_out=plugins=grpc:../client/rpc server.proto 
protoc --go_out=plugins=grpc:../server/rpc server.proto

在client/rpc和server/rpc下生成server.proto的go代码

protoc下载:

链接:pan.baidu.com/s/1pel1cJ82… 提取码:7777

记得将protoc加入系统环境变量

编写Server结构体来实现ServerServer接口

package main
​
import (
    "context"
    "fmt"
    "grpcProject/server/rpc"
)
​
type Server struct {
}
​
func (s Server) Hello(ctx context.Context, request *rpc.Empty) (*rpc.HelloResponse, error) {
    resp := rpc.HelloResponse{Hello: "hello client"}
    return &resp, nil
}
​
func (s Server) Register(ctx context.Context, request *rpc.RegisterRequest) (*rpc.RegisterResponse, error) {
    resp := rpc.RegisterResponse{}
    resp.Uid = fmt.Sprintf("%s.%s", request.GetName(), request.GetPassword())
    return &resp, nil
}
​

使用Server结构体来实现proto文件中Server的2个接口方法。

server端main函数

package main
​
import (
    "fmt"
    "google.golang.org/grpc"
    "grpcProject/server/rpc"
    "log"
    "net"
)
​
func main() {
    lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 8000))
​
    if err != nil {
        log.Fatalf("启动grpc失败")
        return
    }
    grpcServer := grpc.NewServer()
​
    rpc.RegisterServerServer(grpcServer, Server{})
​
    log.Println("service start")
​
    if err := grpcServer.Serve(lis); err != nil {
        log.Fatalf("启动grpc失败")
    }
}
​
func RegisterServerServer(s *grpc.Server, srv ServerServer) {
   s.RegisterService(&_Server_serviceDesc, srv)
}

rpc.RegisterServerServer(grpcServer, Server{})

将实现了ServerServer的结构体Server注册,自此client端调用grpc方法都将调用Server实现的方法

client端main函数

package main
​
import (
    "context"
    "fmt"
    "google.golang.org/grpc"
    "grpcProject/client/rpc"
    "log"
)
​
func main() {
    conn, err := grpc.Dial("127.0.0.1:8000", grpc.WithInsecure())
​
    if err != nil {
        fmt.Println("err : %v", err)
        return
    }
    ServerClient := rpc.NewServerClient(conn)
​
    hello, err := ServerClient.Hello(context.Background(), &rpc.Empty{})
    if err != nil {
        fmt.Println("err : %v", err)
        return
    }
    log.Println(hello, err)
}
​

hello, err := ServerClient.Hello(context.Background(), &rpc.Empty{})

ServerClient调用的Hello方法为Server实现的方法

func (s Server) Hello(ctx context.Context, request rpc.Empty) ( rpc.HelloResponse, error) { resp := rpc.HelloResponse{Hello: "hello client"} return &resp, nil }