- 1.# 下载最新版本23.2的protoc,这个是protobuf代码生成工具,通过proto文件生成对应的代码,根据自己操作系统下载相应文件,这里以windows 64位系统为例
- wget https://github.com/protocolbuffers/protobuf/releases/download/v23.2/protoc-23.2-win64.zip
- # 解压并放在windows本地目录,并配置在Path路径下如D:\Program Files\protoc-23.2-win64\bin,在windows下命令行执行protoc --version检查是否安装配置正确
-
- 2.# 创建go项目grpc-demo,在GoLand IDE编写,并通过下面命令安装grpc核心库protoc,可以GoLand IDE安装protoc插件,实现语法高亮
- go get google.golang.org/grpc
-
- 3.# 在实际开发中最好指定具体的版本,这里是演示使用就直接用latest,在命令行中执行下面两条命令
- go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
- go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
-

service/users.proto内容:
- syntax = "proto3";
- option go_package = "../service";
-
- // 服务和方法
- service Users {
- rpc GetUser (UserGetRequest) returns (UserGetReply) {}
- }
-
- // 请求消息
- message UserGetRequest {
- string email = 1;
- int32 id = 2;
- }
-
- // 响应消息
- message User {
- string id = 1;
- string first_name = 2;
- string last_name = 3;
- int32 age = 4;
- }
-
- message UserGetReply {
- User user = 1;
- }
在service目录下执行以下命令,自动生成pb.go文件
protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative users.proto
server/server.go内容:
- package main
-
- import (
- "context"
- "log"
- "net"
- "os"
-
- users "testgo/service" // 导入之前生成的包
-
- "google.golang.org/grpc"
- )
-
- // userService类型是Users服务的服务处理程序
- type userService struct {
- users.UnimplementedUsersServer // 这个字段对于gRPC中的任何服务实现都是强制性的
- }
-
- func (s *userService) GetUser(ctx context.Context, in *users.UserGetRequest) (*users.UserGetReply, error) {
- // 打印客户端传过来的数据
- log.Printf("已接收到邮件地址: %s, 还有ID: %d", in.Email, in.Id)
-
- // 自定义数据响应给客户端
- u := users.User{
- Id: "user-782911",
- FirstName: "mike",
- LastName: "li",
- Age: 22,
- }
- return &users.UserGetReply{User: &u}, nil
- }
-
- // 向gRPC服务器注册Users服务
- func registerServices(s *grpc.Server) {
- users.RegisterUsersServer(s, &userService{})
- }
-
- // 启动gRPC服务器
- func startServer(s *grpc.Server, l net.Listener) error {
- return s.Serve(l)
- }
-
- func main() {
- listenAddr := os.Getenv("LISTEN_ADDR")
-
- if len(listenAddr) == 0 {
- listenAddr = ":50051"
- }
-
- lis, err := net.Listen("tcp", listenAddr)
-
- if err != nil {
- log.Fatal(err)
- }
-
- s := grpc.NewServer()
- registerServices(s)
-
- log.Fatal(startServer(s, lis))
- }
- package main
-
- import (
- "context"
- "log"
- "os"
- users "testgo/service" // 导入之前生成的包
-
- "google.golang.org/grpc"
- )
-
- // 建立与服务器的连接(通道)
- func setupGrpcConnection(addr string) (*grpc.ClientConn, error) {
- return grpc.DialContext(
- context.Background(),
- addr,
- grpc.WithInsecure(),
- grpc.WithBlock(),
- )
- }
-
- // 创建客户端与Users服务通信
- func getUserServiceClient(conn *grpc.ClientConn) users.UsersClient {
- return users.NewUsersClient(conn)
- }
-
- // 调用Users服务中的GetUser()方法
- func getUser(client users.UsersClient, u *users.UserGetRequest) (*users.UserGetReply, error) {
- return client.GetUser(context.Background(), u)
- }
-
- func main() {
- if len(os.Args) != 2 {
- log.Fatal("缺少gRPC服务器地址")
- }
- conn, err := setupGrpcConnection(os.Args[1])
- if err != nil {
- log.Fatal(err)
- }
- defer conn.Close()
- c := getUserServiceClient(conn)
- result, err := getUser(c, &users.UserGetRequest{
- Email: "mike_li@163.com",
- Id: 8082731,
- })
- if err != nil {
- log.Fatal(err)
- }
-
- // 打印响应
- log.Printf("收到响应: %s %s %s %d\n", result.User.Id, result.User.FirstName, result.User.LastName, result.User.Age)
- }
- # 1.服务端执行(在server文件夹下):
- go run .\server.go
-
- # 2.客户端执行(开启另外一个终端,在client文件夹下):
- go run main.go localhost:50051
![]()
