当前位置: 首页 > news >正文

Golang | gRPC demo

  • 我们来写一个远程加法服务:客户端传入两个整数,服务端返回它们的和。

  • 项目结构如下:

grpc-demo/
├── proto/
│   └── calc.proto
├── server/
│   └── main.go
├── client/
│   └── main.go
  1. 编写proto文件
// proto/calc.protosyntax = "proto3";package calc;option go_package = "grpc-demo/proto;calc";service Calculator {rpc Add (AddRequest) returns (AddResponse);
}message AddRequest {int32 a = 1;int32 b = 2;
}message AddResponse {int32 result = 1;
}
  1. 生成 go 代码
// 1. 安装必要插件
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest// 2. 在项目根目录运行命令生成代码
protoc --go_out=. --go-grpc_out=. proto/calc.proto// 3. 会生成两个文件
proto/calc.pb.go
proto/calc_grpc.pb.go

在这里插入图片描述

  1. 编写服务端代码
// server/main.gopackage mainimport ("context""fmt""log""net"pb "grpc-demo/proto""google.golang.org/grpc"
)type calcServer struct {// gRPC 自动生成的嵌套结构体// 提供一个默认实现,当你忘了实现某个方法时,程序不会 panic,而是自动返回 Unimplemented 错误。// 等价于你默认实现了接口的所有函数(即使你只写了 Add() 一个方法),其他没写的方法会返回 "method Xxx not implemented",编译器不会报错,你的服务也不会挂,只是调用时返回错误。pb.UnimplementedCalculatorServer
}func (s *calcServer) Add(ctx context.Context, req *pb.AddRequest) (*pb.AddResponse, error) {sum := req.A + req.Breturn &pb.AddResponse{Result: sum}, nil
}func main() {lis, err := net.Listen("tcp", ":50051")if err != nil {log.Fatalf("监听失败: %v", err)}s := grpc.NewServer()// 把你自己写的服务实现(&calcServer{})注册到 gRPC 框架中,告诉框架:// “如果有客户端调用 Calculator 服务的 Add 方法,请调用我这个对象里的 Add 方法。”// 把你写好的 calcServer 对象和 Add 方法注册到 grpc.Server 内部的路由表里,告诉它“客户端调用 Add 的时候要调这个函数”。// func RegisterXXXServer(s *grpc.Server, srv XXXServer) 是 protoc 编译 .proto 文件时自动为每个 service 生成的“注册函数”。// 它的作用:把你实现的服务逻辑(结构体对象)注册到 gRPC 框架的内部路由表中,告诉它:“有客户端调用 XXX 这个服务时,应该调用这个对象的方法。”pb.RegisterCalculatorServer(s, &calcServer{}) fmt.Println("服务启动在 :50051")if err := s.Serve(lis); err != nil {log.Fatalf("服务启动失败: %v", err)}
}// [监听端口] —→ [创建gRPC服务器] —→ [注册服务实现] —→ [开始接收请求并处理]
  1. 编写客户端代码
// client/main.gopackage mainimport ("context""fmt""log""time"pb "grpc-demo/proto""google.golang.org/grpc"
)func main() {conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure(), grpc.WithBlock())if err != nil {log.Fatalf("连接失败: %v", err)}defer conn.Close()client := pb.NewCalculatorClient(conn)ctx, cancel := context.WithTimeout(context.Background(), time.Second)defer cancel()req := &pb.AddRequest{A: 3, B: 5}resp, err := client.Add(ctx, req)if err != nil {log.Fatalf("调用失败: %v", err)}fmt.Printf("3 + 5 = %d\n", resp.Result)
}
  1. 运行项目
// 启动服务端
go run server/main.go// 启动客户端(另开一个终端)
go run client/main.go
你写的 .proto 文件↓(protoc 生成)
gRPC 生成接口 + 注册器↓
你实现接口(Add 函数)↓
RegisterCalculatorServer(s, 实现对象)↓
s.Serve(lis) 接受连接↓
接收到 "Calculator.Add" 的请求↓
自动调用你写的 Add 方法↓
返回结果

相关文章:

  • JS 逆向太费劲,试试 JS 注入!
  • 题海拾贝:P1208 [USACO1.3] 混合牛奶 Mixing Milk
  • 流程自动化引擎:让业务自己奔跑
  • 深入理解设计模式之职责链模式
  • 2025年电气工程与轨道交通国际会议:绿色能源与智能交通的创新之路
  • IACEES 2025:创新材料与能源模式,迎接未来的挑战
  • 多元素纳米颗粒:开启能源催化新纪元
  • 【AI算法工程师面试指北】大模型微调中的灾难性遗忘该如何避免?
  • 登高架设作业考试中常见的安全规范考点是什么?
  • element-plus主题换色
  • Ubuntu22.04 重装后,串口无响应
  • tauri2项目打开某个文件夹,类似于mac系统中的 open ./
  • 【Pandas】pandas DataFrame between_time
  • 域名解析怎么查询?有哪些域名解析查询方式?
  • DAX权威指南5:筛选上下文、表操作函数与层级结构
  • c语言实现Linux命令行补全机制
  • 如何训练意志力
  • Android 13中 配置签名文件与内置相应的Apk
  • QGIS新手教程2:线图层与多边形图层基础操作指南(点线互转、中心点提取与WKT导出)
  • Docker安装 | Spug
  • 自然人做音频网站违法吗/网页设计模板网站免费
  • 网站建设还好做吗/搜索引擎优化的根本目的
  • 网站 seo 优化 效果/网站页面布局和样式设计
  • 深圳外贸英语培训/郑州seo优化培训
  • 免费做拍卖网站/如何做好企业推广
  • 网站建设可用性的五个标准/南宁 百度网盘