文章目录
- 前言
- gRPC是什么
- Go语言的gRPC技术栈
- 准备工作
- 接口定义
- 代码生成
- 服务端代码编写
- 客户端代码编写
- 效果演示
- 完整代码链接
- 最后
前言
你好,我是醉墨居士,这篇博客想帮助初学者能够快速入门gRPC,希望能够为你节省宝贵的时间,让时间花费在有价值的事情上
gRPC是什么
gRPC是Google公司基于HTTP/2传输协议与Protobuf 编码协议 开发的跨语言的高性能、开源的远程过程调用(RPC)框架,具有高效的通信机制、跨语言支持、强大的服务定义与拓展能力
Go语言的gRPC技术栈
基于Unix Socket协议或者TCP协议实现HTTP/2协议,在HTTP/2协议的基础上构建了针对Go语言的gRPC核心库,应用程序通过gRPC插件工具生成Stub代码来和gRPC核心库进行交互
准备工作
安装protoc编译器
下载地址:https://github.com/protocolbuffers/protobuf/releases
选择自己对应的操作系统与架构类型的安装包
安装go语言相关的protoc与gRPC插件
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
更新 PATH,使 protoc 编译器能够找到插件
export PATH="$PATH:$(go env GOPATH)/bin"
接口定义
通过编写proto文件来定义接口信息,定义服务和消息
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
代码生成
使用 protoc 编译器将 helloworld.proto 文件编译成 Go 语言的代码 和 gRPC 相关的代码
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
helloworld/helloworld.proto
protoc:这是 Protocol Buffers 编译器的命令行工具。
–proto_path=.:这是一个编译选项,指定了搜索 .proto 文件的目录。在这个例子中,它被设置为当前目录(.),意味着编译器会在当前目录下搜索 .proto 文件。
–go_out=.:这个选项告诉 protoc 编译器生成 Go 语言的代码,并且将生成的代码放在当前目录(.)。
–go_opt=paths=source_relative:这个选项是传递给 Go 语言代码生成器的,paths=source_relative 指定了生成的 Go 代码中的 import 路径应该是相对于源 .proto 文件的路径。
–go-grpc_out=.:这个选项告诉 protoc 编译器生成 Go 语言的 gRPC 代码,并且将生成的代码放在当前目录(.)。
–go-grpc_opt=paths=source_relative:这个选项是传递给 Go 语言 gRPC 代码生成器的,paths=source_relative 指定了生成的 Go gRPC 代码中的 import 路径应该是相对于源 .proto 文件的路径。
helloworld/helloworld.proto:这是指定要编译的 .proto 文件的路径。在这个例子中,.proto 文件位于 helloworld 目录下,文件名为 helloworld.proto。
普通的消息类型代码,用于序列化和反序列化 Protocol Buffers 消息。
gRPC 服务端和客户端代码,用于实现远程过程调用。
这些代码都是根据 helloworld.proto 文件中定义的消息和服务生成的,生成的代码会放置在执行命令的当前目录中。如果你的 .proto 文件中定义了 package,那么生成的 Go 文件将会有相应的 package 名称,并且 import 路径会相对于 .proto 文件的源路径。
服务端代码编写
package main
import (
"context"
"fmt"
"go-examples/grpc/hello"
"net"
"google.golang.org/grpc"
)
// 接口实现
type GreeterServer struct {
hello.UnimplementedGreeterServer
}
// 实现SayHello方法
func (s *GreeterServer) SayHello(ctx context.Context, in *hello.HelloRequest) (*hello.HelloReply, error) {
fmt.Printf("Received: %s\n", in.GetName())
return &hello.HelloReply{Message: "Hello " + in.Name}, nil
}
func main() {
// 创建监听器
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 40404))
if err != nil {
panic(err)
}
defer lis.Close()
// 创建grpc server
s := grpc.NewServer()
// 注册服务
hello.RegisterGreeterServer(s, &GreeterServer{})
// 启动服务
s.Serve(lis)
}
客户端代码编写
package main
import (
"context"
"fmt"
"go-examples/grpc/hello"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
func main() {
// 连接远程服务器
conn, err := grpc.NewClient("localhost:40404", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
panic(err)
}
defer conn.Close()
// 创建客户端实例
cli := hello.NewGreeterClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
// 调用服务端方法
resp, err := cli.SayHello(ctx, &hello.HelloRequest{Name: "world"})
if err != nil {
panic(err)
}
fmt.Printf("Greeting: %s\n", resp.Message)
}
效果演示
完整代码链接
https://github.com/zm50/go-examples/tree/master/grpc
最后
我是醉墨居士,希望用最简单的文章帮助你快速入门Go语言进行gRPC开发,如果对你有所帮助,请多多支持呀