做網(wǎng)站跳轉(zhuǎn)怎么收費(fèi)網(wǎng)絡(luò)營(yíng)銷軟件推廣
gone是可以高效開(kāi)發(fā)Web服務(wù)的Golang依賴注入框架
github地址:https://github.com/gone-io/gone
文檔地址:https://goner.fun/zh/
文章目錄
- 使用gRPC通信
- 編寫(xiě)proto文件,生成golang代碼
- 編寫(xiě)服務(wù)端代碼
- 注冊(cè)客戶端
- 編寫(xiě)配置文件
- 測(cè)試
- 總結(jié)
使用gRPC通信
首先創(chuàng)建一個(gè)grpc目錄,在這個(gè)目錄中初始化一個(gè)golang mod:
mkdir grpc
cd grpc
go mod init grpc
編寫(xiě)proto文件,生成golang代碼
- 編寫(xiě)協(xié)議文件
定義一個(gè)簡(jiǎn)單的Hello服務(wù),包含一個(gè)Say方法
文件名:proto/hello.proto
syntax = "proto3";option go_package="/proto";package Business;service Hello {rpc Say (SayRequest) returns (SayResponse);
}message SayResponse {string Message = 1;
}message SayRequest {string Name = 1;
}
- 生成golang代碼
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
proto/hello.proto
其中,protoc的安裝參考Protocol Buffer 編譯器安裝
編寫(xiě)服務(wù)端代碼
文件名:server/main.go
package mainimport ("context""github.com/gone-io/gone""github.com/gone-io/gone/goner""github.com/gone-io/gone/goner/cmux""google.golang.org/grpc""grpc/proto""log"
)type server struct {gone.Flagproto.UnimplementedHelloServer // 嵌入U(xiǎn)nimplementedHelloServer
}// 重載協(xié)議中定義的服務(wù)
func (s *server) Say(ctx context.Context, in *proto.SayRequest) (*proto.SayResponse, error) {log.Printf("Received: %v", in.GetName())return &proto.SayResponse{Message: "Hello " + in.GetName()}, nil
}// 實(shí)現(xiàn) gone_grpc.Service接口的RegisterGrpcServer方法,該方法在服務(wù)器啟動(dòng)時(shí)會(huì)被自動(dòng)調(diào)用
func (s *server) RegisterGrpcServer(server *grpc.Server) {proto.RegisterHelloServer(server, s)
}func main() {gone.Prepare(func(cemetery gone.Cemetery) error {_ = cmux.Priest(cemetery) // 注冊(cè)cmux,可以讓gRPC服務(wù) 和 HTTP服務(wù)共享一個(gè)端口_ = goner.GrpcServerPriest(cemetery) // 注冊(cè)gRPC服務(wù)器cemetery.Bury(&server{}) // 注冊(cè)gRPC服務(wù)return nil}).// 啟動(dòng)服務(wù)Serve()
}
注冊(cè)客戶端
文件名:client/main.go
package mainimport ("context""fmt""github.com/gone-io/gone""github.com/gone-io/gone/goner""google.golang.org/grpc""grpc/proto""log"
)type helloClient struct {gone.Flagproto.HelloClient // 嵌入HelloClienthost string `gone:"config,server.host"`port string `gone:"config,server.port"`
}// 實(shí)現(xiàn) gone_grpc.Client接口的Address方法,該方法在客戶端啟動(dòng)時(shí)會(huì)被自動(dòng)調(diào)用
// 該方法的作用是告訴客戶端gRPC服務(wù)的地址
func (c *helloClient) Address() string {return fmt.Sprintf("%s:%s", c.host, c.port)
}// 實(shí)現(xiàn) gone_grpc.Client接口的Stub方法,該方法在客戶端啟動(dòng)時(shí)會(huì)被自動(dòng)調(diào)用
// 在該方法中,完成 HelloClient的初始化
func (c *helloClient) Stub(conn *grpc.ClientConn) {c.HelloClient = proto.NewHelloClient(conn)
}func main() {gone.Prepare(func(cemetery gone.Cemetery) error {_ = goner.GrpcClientPriest(cemetery) // 注冊(cè)gRPC客戶端注冊(cè)器Gonercemetery.Bury(&helloClient{}) //注冊(cè)我們的實(shí)現(xiàn)的helloClientreturn nil}).Run(func(in struct {hello *helloClient `gone:"*"`// 在Run方法的參數(shù)中,注入 helloClient}) {// 調(diào)用Say方法,給服務(wù)段發(fā)送消息say, err := in.hello.Say(context.Background(), &proto.SayRequest{Name: "gone"})if err != nil {log.Printf("er:%v", err)return}log.Printf("say result: %s", say.Message)})
}
編寫(xiě)配置文件
文件名:config/default.properties
# 設(shè)置grpc服務(wù)的端口和host
server.port=9001
server.host=127.0.0.1# 設(shè)置客戶端使用的grpc服務(wù)端口和host
server.grpc.port=${server.port}
server.grpc.host=${server.host}
測(cè)試
- 先運(yùn)行服務(wù)端:
go run server/main.go
程序等待請(qǐng)求,屏幕打印內(nèi)容:
2024-06-19 22:02:41.971|INFO|/Users/jim/works/gone-io/gone/goner/grpc/server.go:84||Register gRPC service *main.server
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
- 然后,另外開(kāi)窗口啟動(dòng)客戶端:
go run client/main.go
程序執(zhí)行完退出,屏幕打印內(nèi)容如下:
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:90012024/06/19 22:06:20 say result: Hello gone
- 回到服務(wù)端窗口,可以看到服務(wù)器接收到請(qǐng)求,新打印一行日志:
2024/06/19 22:06:08 Received: gone
總結(jié)
在Gone中使用gRPC,需要完成以下幾步:
-
編寫(xiě)服務(wù)端
- 編寫(xiě)服務(wù)端Goner,匿名嵌入proto協(xié)議生成代碼的 默認(rèn)實(shí)現(xiàn)
- 重載proto文件中定義的接口方法,編寫(xiě)提供服務(wù)的具體業(yè)務(wù)邏輯
- 實(shí)現(xiàn)
gone_grpc.Service
接口的RegisterGrpcServer
方法,在該方法中完成服務(wù)注冊(cè) - 將 服務(wù)端Goner 注冊(cè)到 Gone框架
- 啟動(dòng)服務(wù)
-
編寫(xiě)客戶端
- 編寫(xiě)客戶端Goner,嵌入proto協(xié)議生成代碼的客戶端接口
- 實(shí)現(xiàn)
gone_grpc.Client
接口的Address
和Stub
方法,Address
方法返回服務(wù)端地址,Stub
初始化客服端接口 - 將 客戶端Goner 注冊(cè)到 Gone框架
- 啟動(dòng)客戶端,調(diào)用客服端接口方法
本文的代碼開(kāi)源在: https://github.com/gone-io/gone/tree/main/example/grpc