gRPC支持四种类型的方法,分别是:
- Unary模式
- 客户端流模式
- 服务端流模式
- 双向流模式
其中最常见的是Unary模式(即一元模式),我们在本章节仅介绍Unary模式。
Unary模式,也可以称为"一问一答模式",客户端发送一个请求给服务端,服务端返回一个响应,和一次普通的函数调用类似。 示意图如下:
下面我们来实现一个简单的Unary接口。
要通过grpc提供接口,可以分为以下三个步骤:
- 接口定义(.proto文件)。
- 生成相关代码。
- 服务端开发。
- 客户端开发。
接口定义
我们这里实现一个简单的greet功能,项目目录结构如下:
txt
proto 存放proto文件。
pb 存放生成的go文件。
server 服务端代码。
client 客户端代码。
bin 可执行文件。
proto文件定义如下(greet.proto):
proto
syntax = "proto3";
package proto;
option go_package = "git.gqnotes.com/guoqiang/grpcexercises/greet/pb";
service GreetService {
rpc Greet(GreetRequest) returns(GreetResponse) {}
}
message GreetRequest {
string greeting = 1;
}
message GreetResponse {
string result = 1;
}
定义Makefile,方便执行相关操作:
makefile
tidy:
go mod tidy
greet-gen:
protoc -Igreet/proto/ --go_out=./greet --go_opt=module=git.gqnotes.com/guoqiang/grpcexercises/greet --go-grpc_out=./greet --go-grpc_opt=module=git.gqnotes.com/guoqiang/grpcexercises/greet greet/proto/*.proto
greet-build:
go build -o ./greet/bin/server-osx ./greet/server
go build -o ./greet/bin/client-osx ./greet/client
.PHONY: tidy greet-gen greet-build
生成相关代码
在项目目录(greet上级目录)下执行如命令:
sh
make greet-gen
执行成功,在pb目录下生成相关文件。
服务端开发
在server目录下添加两个文件:
- main.go,服务入口文件。
- Greet.go,Greet方法实现。
代码如下:
main.go
go
package main
import (
"git.gqnotes.com/guoqiang/grpcexercises/greet/pb"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
"log"
"net"
)
func main() {
// 实现服务端逻辑,监听5632端口
lis, err := net.Listen("tcp", ":5632")
if err != nil {
log.Fatalf("failed to listen: %v", err)
return
}
s := grpc.NewServer()
// 注册服务
pb.RegisterGreetServiceServer(s, &Server{})
reflection.Register(s)
log.Println("grpc server start")
if err = s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
return
}
}
type Server struct {
pb.UnimplementedGreetServiceServer
}
Greet.go ```go package main
import ( "context" "git.gqnotes.com/guoqiang/grpcexercises/greet/pb" "log" "time" )
// Greet greet func (s *Server) Greet(ctx context.Context, req *pb.GreetRequest) (*pb.GreetResponse, error) { log.Printf("Greet function was invoked with %v\n", req)
css
result := "Hello " + req.GetGreeting() + ", now time is:" + time.Now().String()
res := &pb.GreetResponse{
Result: result,
}
return res, nil
}
less
</details>
## 客户端开发
在client目录下添加客户端代码,有两个文件:
- main.go,程序入口文件。
- Greet.go,具体方法文件。
文件内容如下:
<details>
<summary>main.go</summary>
```go
package main
import (
"git.gqnotes.com/guoqiang/grpcexercises/greet/pb"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"log"
)
func main() {
conn, err := grpc.Dial(":5632", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("failed to dial: %v", err)
return
}
defer conn.Close()
// 实例化客户端
client := pb.NewGreetServiceClient(conn)
// 调用方法
Greet(client)
}
Greet.go
go
package main
import (
"context"
"git.gqnotes.com/guoqiang/grpcexercises/greet/pb"
"log"
)
func Greet(client pb.GreetServiceClient) {
response, err := client.Greet(context.Background(), &pb.GreetRequest{
Greeting: "xiaoming",
})
if err != nil {
log.Fatalf("failed to call Greet: %v", err)
return
}
log.Printf("response:%+v\n", response)
}
执行
在项目目录下执行make tidy,拉取相关库,然后执行 make greet-build,生成可执行文件。 然后在命令行下执行如下命令,启动服务端程序:
bash
./greet/bin/server-osx
执行如下命令,测试客户端文件:
bash
./greet/bin/client-osx
执行结果如下:
txt
2023/12/02 15:02:26 response:result:"Hello xiaoming now time is:2023-12-02 15:02:26.443767 +0800 CST m=+1268.825308543"
代码地址。
本文由mdnice多平台发布