Go语言实现开发一个简单的gRPC Demo

 更新时间:2023年07月16日 11:08:02   作者:不背锅运维  
这篇文章主要为大家详细介绍了如何利用Go语言实现开发一个简单的gRPC Demo,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下

Part1先决条件

获得并安装好Golang(https://go.dev/doc/install

Protocol buffer compiler(protobuf编译器), protoc version 3(protoc工具版本建议为3版本),获得并安装:https://github.com/protocolbuffers/protobuf/releases

安装protocol编译器的Go插件

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

Part2开发环境准备

准备go环境

wget https://go.dev/dl/go1.20.5.linux-amd64.tar.gz
tar -zxf go1.20.5.linux-amd64.tar.gz
mv go /usr/local/

安装protobuf编译器protoc

wget https://github.com/protocolbuffers/protobuf/releases/download/v23.4/protoc-23.4-linux-x86_64.zip
mkdir protoc-23.4
mv protoc-23.4-linux-x86_64.zip
cd protoc-23.4
unzip protoc-23.4-linux-x86_64.zip
rm -rf protoc-23.4-linux-x86_64.zip
cd ..
mv protoc-23.4 /usr/local/

添加相关环境变量

export GOROOT="/usr/local/go"
export GOPATH="/home/tantianran/goCode"
export GOPROXY="https://goproxy.cn,direct"
export GO111MODULE="on"
export PATH=$PATH:$GOROOT/bin:$GOPATH:$GOPATH/bin
export PROTOC_HOME=/usr/local/protoc-23.4
export PATH=$PATH:$PROTOC_HOME/bin

Part3实战:开发一个简单的gRPC Demo

1.创建user-service模块

tantianran@go-dev:~/goCode/src$ mkdir user-service
tantianran@go-dev:~/goCode/src$ cd user-service/
tantianran@go-dev:~/goCode/src/user-service$ go mod init

2.使用protobuf idl语言定义服务接口

创建service包

tantianran@go-dev:~/goCode/src/user-service$ mkdir service
tantianran@go-dev:~/goCode/src/user-service$ cd service/

service/users.proto内容:

syntax = "proto3";
option go_package = "user-service/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; // 嵌套
}

3.生成客户端和服务端代码

首先安装用于编译器的go语言插件protoc-gen-go

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest

开始生成

tantianran@go-dev:~/goCode/src/user-service/service$ protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative users.proto
tantianran@go-dev:~/goCode/src/user-service/service$ ls -l
total 24
-rw-rw-r-- 1 tantianran tantianran   37 Jul 11 10:05 go.mod
-rw-rw-r-- 1 tantianran tantianran 3387 Jul 11 10:10 users_grpc.pb.go
-rw-rw-r-- 1 tantianran tantianran 8984 Jul 11 10:10 users.pb.go
-rw-rw-r-- 1 tantianran tantianran  362 Jul 11 10:09 users.proto

4.编写服务器

创建server包

tantianran@go-dev:~/goCode/src$ cd user-service/
tantianran@go-dev:~/goCode/src/user-service$ mkdir server
tantianran@go-dev:~/goCode/src/user-service$ cd server/

server/server.go

package main
import (
 "context"
 "log"
 "net"
 "os"
 users "user-service/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-782935",
  FirstName: "tan",
  LastName:  "tianran",
  Age:       30,
 }
 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))
}

5.编写客户端

tantianran@go-dev:~/goCode/src$ cd user-service/
tantianran@go-dev:~/goCode/src/user-service$ mkdir client/
tantianran@go-dev:~/goCode/src/user-service$ cd client/

client/main.go

package main
import (
 "context"
 "log"
 "os"
 users "user-service/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: "tantianran@qq.com",
  Id:    801896,
 })
 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)
}

Part4验证效果

服务器

tantianran@go-dev:~/goCode/src/user-service/server$ go run server.go
2023/07/12 00:59:01 已接收到邮件地址: tantianran@qq.com, 还有ID: 801896

客户端

tantianran@go-dev:~/goCode/src/user-service/client$ go run main.go localhost:50051
2023/07/12 00:59:01 收到响应: user-782935 tan tianran 30

以上就是Go语言实现开发一个简单的gRPC Demo的详细内容,更多关于Go gRPC的资料请关注脚本之家其它相关文章!

相关文章

  • GO语言协程创建使用并通过channel解决资源竞争

    GO语言协程创建使用并通过channel解决资源竞争

    这篇文章主要为大家介绍了GO语言协程创建使用并通过channel解决资源竞争,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • golang xorm 自定义日志记录器之使用zap实现日志输出、切割日志(最新)

    golang xorm 自定义日志记录器之使用zap实现日志输出、切割日志(最新)

    这篇文章主要介绍了golang xorm 自定义日志记录器,使用zap实现日志输出、切割日志,包括连接postgresql数据库的操作方法及 zap日志工具 ,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10
  • Go使用Google Gemini Pro API创建简单聊天机器人

    Go使用Google Gemini Pro API创建简单聊天机器人

    这篇文章主要为大家介绍了Go使用Google Gemini Pro API创建简单聊天机器人实现过程详解,本文将通过最新的gemini go sdk来实现命令行聊天机器人
    2023-12-12
  • golang 各种排序大比拼实例

    golang 各种排序大比拼实例

    这篇文章主要介绍了golang 各种排序大比拼实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 浅析Go设计模式之Facade(外观)模式

    浅析Go设计模式之Facade(外观)模式

    本文将介绍外观模式的概念、结构和工作原理,并提供一些在Go中实现外观模式的示例代码,通过使用外观模式,可以降低代码的耦合度,提高代码的可维护性和可读性,需要的朋友可以参考下
    2023-05-05
  • GoFrame框架gredis优雅的取值和类型转换

    GoFrame框架gredis优雅的取值和类型转换

    这篇文章主要为大家介绍了GoFrame框架gredis优雅的取值和类型转换,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Golang中panic的实现示例

    Golang中panic的实现示例

    这篇文章主要介绍了Golang中panic的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-06-06
  • 手把手带你走进Go语言之循环语句

    手把手带你走进Go语言之循环语句

    在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句。一组被重复执行的语句称之为循环体,能否继续重复,决定循环的终止条件,本文给大家介绍的非常详细,跟着小编往下看吧
    2021-09-09
  • go使用makefile脚本编译应用的方法小结

    go使用makefile脚本编译应用的方法小结

    makefile可以看作是make工具的脚本文件, 而make主要用来处理一系列命令。常用的比如用来编译和打包文件, 在C/C++的编译打包中应用最广泛了,这篇文章主要介绍了go使用makefile脚本编译应用,需要的朋友可以参考下
    2022-08-08
  • Golang中基于HTTP协议的网络服务

    Golang中基于HTTP协议的网络服务

    HTTP协议是基于TCP/IP协议栈的,并且它也是一个面向普通文本的协议。这篇文章主要详细介绍了Golang中基于HTTP协议的网络服务,感兴趣的小伙伴可以借鉴一下
    2023-04-04

最新评论