Skip to content
This repository was archived by the owner on Jun 5, 2025. It is now read-only.

Commit 45cd26e

Browse files
author
dapeng
committed
update
1 parent 361dc1c commit 45cd26e

File tree

4 files changed

+214
-3
lines changed

4 files changed

+214
-3
lines changed

docs/.vuepress/config.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,11 @@ module.exports = {
193193
text: '分布式锁 + 分布式缓存',
194194
link: '/zh/guide/redis',
195195
}, {
196-
text: 'cron 格式的任务',
196+
text: '配置定时任务',
197197
link: '/zh/guide/schedule.md',
198+
}, {
199+
text: '使用gRPC',
200+
link: '/zh/guide/grpc.md',
198201
}],
199202
}, {
200203
text: "效率提升",

docs/zh/goners/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ next: ../
3232
|redis|封装`github.com/gomodule/redigo/redis`,用于操作redis,提供redis缓存和redis分布式锁的功能|[利用redis提供分布式锁和分布式缓存](../guide/redis.md)|
3333
|schedule|封装`github.com/robfig/cron/v3`,提供定时任务的能力|[用cron表达式配置定时任务](https://goner.fun/zh/guide/schedule.html)|
3434
|urllib|封装`github.com/imroc/req/v3`,提供http调用能力|-|
35-
|grpc|提供开发grpc服务端和客户端的能力|-|
35+
|grpc|提供开发grpc服务端和客户端的能力|[使用gRPC](https://goner.fun/zh/guide/grpc.html)|
3636
|cmux|封装`github.com/soheilhy/cmux`,是统一端口可以提供混合服务的能力|-|
3737
|zap|封装`go.uber.org/zap`,实现`gone.Logger`日志接口,可以替换`logrus`实现更高效的日志输出|-|
3838
|viper|封装`github.com/spf13/viper`,用于替换配置接口默认实现,可以支持丰富的配置文件格式|-|

docs/zh/guide/grpc.md

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
---
2+
sidebar: auto
3+
prev: ./schedule
4+
next: ./auto-gen-priest
5+
---
6+
7+
# 使用gRPC
8+
首先创建一个grpc目录,在这个目录中初始化一个golang mod:
9+
```bash
10+
mkdir grpc
11+
cd grpc
12+
go mod init grpc
13+
```
14+
15+
## 编写proto文件,生成golang代码
16+
- 编写协议文件
17+
定义一个简单的Hello服务,包含一个Say方法
18+
文件名:proto/hello.proto
19+
```proto
20+
syntax = "proto3";
21+
22+
option go_package="/proto";
23+
24+
package Business;
25+
26+
service Hello {
27+
rpc Say (SayRequest) returns (SayResponse);
28+
}
29+
30+
message SayResponse {
31+
string Message = 1;
32+
}
33+
34+
message SayRequest {
35+
string Name = 1;
36+
}
37+
```
38+
- 生成golang代码
39+
40+
```bash
41+
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
42+
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
43+
protoc --go_out=. --go_opt=paths=source_relative \
44+
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
45+
proto/hello.proto
46+
```
47+
> 其中,protoc的安装参考[Protocol Buffer 编译器安装](https://blog.csdn.net/waitdeng/article/details/139248507)
48+
49+
50+
## 编写服务端代码
51+
文件名:server/main.go
52+
```go
53+
package main
54+
55+
import (
56+
"context"
57+
"github.com/gone-io/gone"
58+
"github.com/gone-io/gone/goner"
59+
"github.com/gone-io/gone/goner/cmux"
60+
"google.golang.org/grpc"
61+
"grpc/proto"
62+
"log"
63+
)
64+
65+
type server struct {
66+
gone.Flag
67+
proto.UnimplementedHelloServer // 嵌入UnimplementedHelloServer
68+
}
69+
70+
// 重载协议中定义的服务
71+
func (s *server) Say(ctx context.Context, in *proto.SayRequest) (*proto.SayResponse, error) {
72+
log.Printf("Received: %v", in.GetName())
73+
return &proto.SayResponse{Message: "Hello " + in.GetName()}, nil
74+
}
75+
76+
// 实现 gone_grpc.Service接口的RegisterGrpcServer方法,该方法在服务器启动时会被自动调用
77+
func (s *server) RegisterGrpcServer(server *grpc.Server) {
78+
proto.RegisterHelloServer(server, s)
79+
}
80+
81+
func main() {
82+
gone.
83+
Prepare(func(cemetery gone.Cemetery) error {
84+
_ = cmux.Priest(cemetery) // 注册cmux,可以让gRPC服务 和 HTTP服务共享一个端口
85+
86+
_ = goner.GrpcServerPriest(cemetery) // 注册gRPC服务器
87+
88+
cemetery.Bury(&server{}) // 注册gRPC服务
89+
return nil
90+
}).
91+
// 启动服务
92+
Serve()
93+
}
94+
```
95+
96+
## 注册客户端
97+
文件名:client/main.go
98+
```go
99+
package main
100+
101+
import (
102+
"context"
103+
"fmt"
104+
"github.com/gone-io/gone"
105+
"github.com/gone-io/gone/goner"
106+
"google.golang.org/grpc"
107+
"grpc/proto"
108+
"log"
109+
)
110+
111+
type helloClient struct {
112+
gone.Flag
113+
proto.HelloClient // 嵌入HelloClient
114+
115+
host string `gone:"config,server.host"`
116+
port string `gone:"config,server.port"`
117+
}
118+
119+
// 实现 gone_grpc.Client接口的Address方法,该方法在客户端启动时会被自动调用
120+
// 该方法的作用是告诉客户端gRPC服务的地址
121+
func (c *helloClient) Address() string {
122+
return fmt.Sprintf("%s:%s", c.host, c.port)
123+
}
124+
125+
// 实现 gone_grpc.Client接口的Stub方法,该方法在客户端启动时会被自动调用
126+
// 在该方法中,完成 HelloClient的初始化
127+
func (c *helloClient) Stub(conn *grpc.ClientConn) {
128+
c.HelloClient = proto.NewHelloClient(conn)
129+
}
130+
131+
func main() {
132+
gone.
133+
Prepare(func(cemetery gone.Cemetery) error {
134+
_ = goner.GrpcClientPriest(cemetery) // 注册gRPC客户端注册器Goner
135+
136+
cemetery.Bury(&helloClient{}) //注册我们的实现的helloClient
137+
return nil
138+
}).
139+
Run(func(in struct {
140+
hello *helloClient `gone:"*"`// 在Run方法的参数中,注入 helloClient
141+
}) {
142+
// 调用Say方法,给服务段发送消息
143+
say, err := in.hello.Say(context.Background(), &proto.SayRequest{Name: "gone"})
144+
if err != nil {
145+
log.Printf("er:%v", err)
146+
return
147+
}
148+
log.Printf("say result: %s", say.Message)
149+
})
150+
}
151+
```
152+
153+
## 编写配置文件
154+
文件名:config/default.properties
155+
```properties
156+
# 设置grpc服务的端口和host
157+
server.port=9001
158+
server.host=127.0.0.1
159+
160+
# 设置客户端使用的grpc服务端口和host
161+
server.grpc.port=${server.port}
162+
server.grpc.host=${server.host}
163+
```
164+
165+
166+
## 测试
167+
- 先运行服务端:
168+
```bash
169+
go run server/main.go
170+
```
171+
程序等待请求,屏幕打印内容:
172+
```log
173+
2024-06-19 22:02:41.971|INFO|/Users/jim/works/gone-io/gone/goner/grpc/server.go:84||Register gRPC service *main.server
174+
2024-06-19 22:02:41.971|INFO|/Users/jim/works/gone-io/gone/goner/grpc/server.go:88||gRPC server now listen at 127.0.0.1:9001
175+
```
176+
177+
- 然后,另外开窗口启动客户端:
178+
```bash
179+
go run client/main.go
180+
```
181+
程序执行完退出,屏幕打印内容如下:
182+
```log
183+
2024-06-19 22:06:20.713|INFO|/Users/jim/works/gone-io/gone/goner/grpc/client.go:59||register gRPC client *main.helloClient on address 127.0.0.1:9001
184+
185+
2024/06/19 22:06:20 say result: Hello gone
186+
```
187+
188+
- 回到服务端窗口,可以看到服务器接收到请求,新打印一行日志:
189+
```log
190+
2024/06/19 22:06:08 Received: gone
191+
```
192+
193+
## 总结
194+
在Gone中使用gRPC,需要完成以下几步:
195+
- 编写服务端
196+
1. 编写服务端Goner,匿名嵌入proto协议生成代码的 默认实现
197+
2. 重载proto文件中定义的接口方法,编写提供服务的具体业务逻辑
198+
3. 实现`gone_grpc.Service`接口的`RegisterGrpcServer`方法,在该方法中完成服务注册
199+
4. 将 服务端Goner 注册到 Gone框架
200+
5. 启动服务
201+
202+
- 编写客户端
203+
1. 编写客户端Goner,嵌入proto协议生成代码的客户端接口
204+
2. 实现`gone_grpc.Client`接口的`Address``Stub`方法,`Address`方法返回服务端地址,`Stub`初始化客服端接口
205+
3. 将 客户端Goner 注册到 Gone框架
206+
4. 启动客户端,调用客服端接口方法
207+
208+
本文的代码开源在 [Gone-io/grpc](https://github.com/gone-io/gone/tree/main/example/grpc)

docs/zh/guide/schedule.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
sidebar: auto
33
prev: ./redis
4-
next: ./auto-gen-priest
4+
next: ./grpc
55
---
66

77
# 用cron表达式配置定时任务

0 commit comments

Comments
 (0)