目录结构
grpc
--client
--main.go
--server
--main.go
--pb //命令生成
-- hello.pb.go
-- hello_grpc.pb.go
hello.proto
go.mod //自动生成
第一步 写好proto文件
grpc/chello.proto
syntax = "proto3"; //协议版本
option go_package="/pb"; // 路径 及包名
service Hello {
rpc SayHello (HelloReq) returns (HelloRes){}
}
message HelloReq {
string name =1;
}
message HelloRes {
string msg = 1;
}
第二步 生成grpc文件,命令行执行以下命令
protoc --go_out=. --go-grpc_out=. .\hello.proto
第三步
编写服务端代码
grpc/server/main.go文件
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"grpc/pb"
"net"
)
func main() {
listen, err := net.Listen("tcp", ":50011")//监听50011端口, 端口号可做调整
if err != nil {
panic(err)
}
s := grpc.NewServer() //启动grpc服务
pb.RegisterHelloServer(s, &server{}) //grpc 服务注册
fmt.Printf("server listening at %v\n", listen.Addr())
if err := s.Serve(listen); err != nil {//提供grpc服务
panic(err)
}
}
type server struct {
pb.UnimplementedHelloServer
}
func (s *server) SayHello(ctx context.Context, in *pb.HelloReq) (*pb.HelloRes, error) {
return &pb.HelloRes{
Msg: "你好 " + in.GetName(),
}, nil
}
第四 编写客户端请求代码
/grpc/client/main.go
package main
import (
"context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"grpc/pb"
"log"
"time"
)
func main() {
conn, err := grpc.Dial("localhost:50011", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("can not connect: %v\n", err)
}
defer conn.Close()
c := pb.NewHelloClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := c.SayHello(ctx, &pb.HelloReq{Name: "张三"})
if err != nil {
log.Fatalf("can not greet: %v\n", err)
}
log.Printf("Greeting:%s\n", r.GetMsg())
}
第五步 启动
- 先启动服务端
- 启动客户端,观察日志打印如下
2023/01/31 11:41:59 Greeting:你好 张三