go语言-gRPC简单实现
gRPC简单实现
0.RPC介绍
- RPC时远程过程调用,是计算机通信协议。它可以通过运行的一台计算机的程序取调用另一个地址空间子程序。RPC是一CS模式。通过发送-接收进行交互
- 而gRPC是一个开源的RPC框架,能够在任意环境中,最初谷歌进行开发,后来开源。它能够解决不同语言和环境间通信的复杂度。
1.安装
-
安装gRPC(容易timeout...)
go get -u google.golang.org/grpc
-
安装Protocol BUffers
- mac系统,我安装时 protoc-3.11.4-osx-x86_64.zip
-
安装protoc-gen-go
go get -u github.com/golang/protobuf/protoc-gen-go
-
需要注意:将下载protoc和protoc-gen-go添加到环境变量里面。
vi ~/.bash_profile #添加环境变量: // protoc-gen-go 添加环境变量 export PATH=$PATH:/Users/xujunkai/go/bin/ // protocol buffers 添加环境变量 export PATH=$PATH:/Users/xujunkai/pb_program/protoc-3.11.4-osx-x86_64/bin/ # 刷新bash_ source ~/.bash_profile
2.一个简单demo
-
目录结果如下:
./gRPC_demo ├── go.mod ├── go.sum └── helloworld ├── client │ └── client.go │ ├── client.py ├── pb │ ├── helloworld.pb.go │ └── helloworld.proto └── server └── server.go
-
首选需要编写proto代码,Protocol Buffers时一种与语言无关,平台无关的可扩展机制,用于序列化结构化数据。使用Protocol Buffers可以一次定义结构化的数据,然后可以使用特殊生成的源代码轻松地再各种数据流中使用各种语言编写和读取结构化数据。
-
helloworld.proto 编写:
syntax = "proto3"; //声明版本, v3版本 package pb; //声明包名 // 定义一个服务 service Greeter { // 方法名字叫:SayHello // HelloRequest --> HelloReply rpc SayHello (HelloRequest) returns (HelloReply) {} } // 请求消息 message HelloRequest { string message = 1 } // 响应消息 message HelloReply { string message = 1 }
-
在gRPC_demo/helloworld/pb执行下列语句生成go语言源代码
protoc -I helloworld/ helloworld/pb/helloworld.proto --go_out=plugins=grpc:helloworld //指定倒入文件路径 //指定生成C++路径 // --go_out 生成go代码路径
-
服务端:server
package main import ( "fmt" "net" pb "gRPC_demo/helloworld/pb" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/reflection" ) type server struct{} func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { return &pb.HelloReply{Message: "Hello " + in.Name}, nil } func main() { // 监听本地的8972端口 lis, err := net.Listen("tcp", ":8972") if err != nil { fmt.Printf("failed to listen: %v", err) return } s := grpc.NewServer() // 创建gRPC服务器 pb.RegisterGreeterServer(s, &server{}) // 在gRPC服务端注册服务 reflection.Register(s) //在给定的gRPC服务器上注册服务器反射服务 // Serve方法在lis上接受传入连接,为每个连接创建一个ServerTransport和server的goroutine。 // 该goroutine读取gRPC请求,然后调用已注册的处理程序来响应它们。 err = s.Serve(lis) if err != nil { fmt.Printf("failed to serve: %v", err) return } }
-
编写客户端 client
package main import ( "context" "fmt" pb "gRPC_demo/helloworld/pb" "google.golang.org/grpc" ) func main() { // 连接服务器 conn, err := grpc.Dial(":8972", grpc.WithInsecure()) if err != nil { fmt.Printf("faild to connect: %v", err) } defer conn.Close() c := pb.NewGreeterClient(conn) // 调用服务端的SayHello r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: "q1mi"}) if err != nil { fmt.Printf("could not greet: %v", err) } fmt.Printf("Greeting: %s !\n", r.Message) }
-
先启动客户端,再启动服务端。
// 打印结果 Greeting:Helloqiqi !
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库