golang使用grpc通信入门(从零到一)

这里是小奏 ,觉得文章不错可以关注公众号小奏技术

环境准备

安装Protocol Buffers

目前最新版本是27.0-rc1

github下载地址

根据自己的系统选择不同的版本,我这里是arm架构,所以选择arm压缩包即可

解压完成后就是这个样子

然后直接执行 bin目录下面的protoc脚本

执行完后再执行protoc --version看是否安装成功

可以看到我的版本是libprotoc 3.21.9

安装protocol编译插件

shell 复制代码
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28

该插件会根据.proto文件生成一个后缀为.pb.go的文件,包含所有.proto文件中定义的类型及其序列化方法。

shell 复制代码
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2

该插件会生成一个后缀为_grpc.pb.go的文件,其中包含: 一种接口类型(或存根) ,供客户端调用的服务方法。 服务器要实现的接口类型。

上述命令会默认将插件安装到$GOPATH/bin

为了protoc编译器能找到这些插件,请确保你的$GOPATH/bin在环境变量中。

可以执行如下命令设置环境变量

shell 复制代码
export PATH="$PATH:$(go env GOPATH)/bin"

检查是否安装成功

shell 复制代码
protoc-gen-go --version

protoc-gen-go-grpc --version

实战

整体目录

引入grpc依赖

shell 复制代码
go get -u google.golang.org/grpc

编写 hello.proto 文件

proto 复制代码
syntax = "proto3";

package proto;

option go_package = "./;proto";

// 定义HelloService
service HelloService {
  // 定义一个SayHello方法
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// HelloRequest消息包含一个greeting字段
message HelloRequest {
  string greeting = 1;
}

// HelloReply消息包含一个response字段
message HelloReply {
  string response = 1;
}

生成go文件

这里主要是生成 helloworld.pb.gohelloworld_grpc.pb.go 文件

执行命令

shell 复制代码
 protoc --go_out=. --go-grpc_out=. hello.proto

编写服务端代码

go 复制代码
package main

import (
	"context"
	"google.golang.org/grpc"
	"java-to-go-learning/student/grpc-demo/proto"
	"log"
	"net"
)

// server用于实现hello.HelloServiceServer
type server struct {
	proto.UnimplementedHelloServiceServer
}

// SayHello实现hello.HelloServiceServer接口
func (s *server) SayHello(ctx context.Context, in *proto.HelloRequest) (*proto.HelloReply, error) {
	log.Printf("Received: %v", in.GetGreeting())
	return &proto.HelloReply{Response: "Hello " + in.GetGreeting()}, nil
}

func main() {
	lis, err := net.Listen("tcp", ":50051")
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}
	s := grpc.NewServer()
	proto.RegisterHelloServiceServer(s, &server{})
	log.Printf("server listening at %v", lis.Addr())
	if err := s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}

编写客户端代码

go 复制代码
package main

import (
	"context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"java-to-go-learning/student/grpc-demo/proto"
	"log"
	"time"
)

func main() {
	// 设置服务端地址
	address := "localhost:50051"
	conn, err := grpc.Dial(address, grpc.WithTransportCredentials(insecure.NewCredentials()))

	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	c := proto.NewHelloServiceClient(conn)

	ticker := time.NewTicker(2 * time.Second)
	defer ticker.Stop()

	for range ticker.C {
		// 调用服务端的SayHello
		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
		r, err := c.SayHello(ctx, &proto.HelloRequest{Greeting: "world"})
		if err != nil {
			log.Fatalf("could not greet: %v", err)
		}
		log.Printf("Greeting: %s", r.GetResponse())
		cancel() // 确保在下一次循环开始前取消上下文
	}
}

运行效果

  • client
yaml 复制代码
2024/05/05 13:51:29 Greeting: Hello world
2024/05/05 13:51:31 Greeting: Hello world
2024/05/05 13:51:33 Greeting: Hello world
2024/05/05 13:51:35 Greeting: Hello world
2024/05/05 13:51:37 Greeting: Hello world
2024/05/05 13:51:39 Greeting: Hello world
2024/05/05 13:51:41 Greeting: Hello world
  • server
yaml 复制代码
2024/05/05 13:51:24 server listening at [::]:50051
2024/05/05 13:51:29 Received: world
2024/05/05 13:51:31 Received: world
2024/05/05 13:51:33 Received: world
2024/05/05 13:51:35 Received: world
2024/05/05 13:51:37 Received: world
2024/05/05 13:51:39 Received: world
2024/05/05 13:51:41 Received: world

参考

相关推荐
笃行3509 小时前
向量数据库单独建一套,这笔账划不划算
后端
weixin_4316004410 小时前
Agent Workflow 学习向:Code 节点,比模板更强的变量加工
后端·python·学习·ai·
Rain的Java大神之路10 小时前
短信接口被狂刷怎么处理
java·运维·后端·web安全·面试·架构·xss
Lost of 程序猿11 小时前
AOP 实战:面向切面编程从理论到落地
后端·asp.net·aop·面向切片变成
Lost of 程序猿12 小时前
ASP.NET Core 认证授权实战:从 JWT 到 Policy,设计一套企业级 RBAC 权限系统
后端·asp.net
Lost of 程序猿12 小时前
ASP.NET Core 后台任务全景:从 BackgroundService 到 Channel 队列,再到分布式调度
后端·asp.net·.netcore
倾颜12 小时前
NestJS 核心概念梳理:从 Module、Controller 到 Guard、Interceptor
后端·node.js·nestjs
东风破_13 小时前
JWT 1:从一个登录请求开始,理解 React 项目里的 API 层与 Mock
前端·后端
东风破_13 小时前
JWT 3:为什么 Token 要放进 Authorization?Axios 拦截器到底解决了什么?
前端·后端
东风破_13 小时前
JWT 5:路由守卫是什么?把整个 JWT 登录鉴权流程串起来
前端·后端