当前位置: 首页 > 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 方法↓
返回结果
http://www.xdnf.cn/news/696493.html

相关文章:

  • C++23 <spanstream>:基于 std::span 的高效字符串流处理
  • 软件检测:确保品质关键步骤,企业该如何选择检测方式?
  • 王树森推荐系统公开课 排序05:排序模型的特征
  • 28、请求处理-【源码分析】-请求映射原理
  • 《仿盒马》app开发技术分享-- 确认订单页(业务逻辑)(端云一体)
  • 便携式遥测自跟踪天线
  • 大语言模型推理优化技术综述(The Art of LLM Inference)
  • Oracle基础知识(五)——ROWID ROWNUM
  • 前端开发定时,ES学习,java集合
  • 大数据学习笔记
  • 一种白平衡增益计算中白点权重计算简易实现方式
  • 【备忘】php命令行异步执行超长时间任务
  • Linux云计算训练营笔记day18(Python)
  • (25年5.28)ChatGPT Plus充值教程与实用指南:附国内外使用案例与模型排行
  • 【第2章 绘制】2.12 高级路径操作
  • MySQL 表内容的增删查改 -- CRUD操作,聚合函数,group by 子句
  • 英一真题阅读单词笔记 17年
  • 06.概念二:神经网络
  • 【进口商品防伪页面真假识别指南:从理论到实战的避雷手册】
  • Server 9 ,在 VMware 虚拟机上安装 Windows 系统完整指南
  • 【行动指南】大一如何高效备考java
  • RFID周边解决方案
  • 高温炉制造企业Odoo ERP实施规划与深度分析报告
  • ClamAV使用
  • spring sentinel
  • 运营商地址和ip属地一样吗?怎么样更改ip属地地址
  • 4. Qt对话框(1)
  • zynq 级联多个ssd方案设计(ECAM BUG修改)
  • Springboot 项目一启动就获取HttpSession
  • QT6 关于使用MSVC2019,UI设计师自定义控件的制作和QT Cretor里面调用