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

grpc 快速入门

gRPC 是一个现代的远程过程调用(RPC)框架,由 Google 开发。它使用 HTTP/2 作为传输协议,并采用 Protocol Buffers(protobuf)作为接口描述语言(IDL)。gRPC 提供高效的通信、语言无关性和跨平台支持,非常适合构建分布式系统。

准备接口描述文件即 IDL

	// /home/zhangshixing/protoc/temp/hello.proto// 指定proto版本syntax = "proto3";// 指定包名package mypackage;// 指定文件生成的路径和包名// ./hello为路径// mytest为生成的包名// 如果指定的go_package="./hello";则包名和路径同名(如果路径有多层,则包名和路径的最后一层相同)//option go_package="./hello;mytest";option go_package="./hello";// 定义Hello服务service Hello {// 定义SayHello方法rpc SayHello(HelloRequest) returns (HelloReply) {}}// HelloRequest 请求结构message HelloRequest {string name = 1;string age = 2;}// HelloReply 响应结构message HelloReply {string message = 1;}

生成代码

利用上文定义的接口文件,生成 golang 代码:

protoc -I . --go_out=plugins=grpc:. hello.proto  生成 hello.pb.go 文件生成的代码主要是:结构体的编解码序列化代码 和 用于创建和发起 RPC 调用的桩代码

服务端代码

本质就是启动一个 rpcServer 监听指定端口,其中 pb.RegisterHelloServer(rpcServer, &helloSever) 的分析如下:

  1. RegisterHelloServer 是告诉 rpcServer 什么请求由谁处理;作用和普通 web server 的路由一样。
  2. HelloServer 的 sayHello 的具体逻辑是开发人员自定义实现的,不过其入参和返回值已经由IDL决定了
package mainimport (pb "awesomeProject/libadv/grpcdbg/hello""context""flag""fmt""google.golang.org/grpc""log""net"
)type HelloServer struct {
}func (*HelloServer) SayHello(ctx context.Context, request *pb.HelloRequest) (*pb.HelloReply, error) {fmt.Printf("In the sayHello, param = %s, age = %s\n", request.GetName(), request.GetAge())var helloReply pb.HelloReplyhelloReply.Message = fmt.Sprintf("Hello %s", request.GetName())return &helloReply, nil
}var (port = flag.Int("port", 50052, "The server port")
)func main() {/** 修改 hello.proto 后,执行  protoc -I . --go_out=plugins=grpc:. hello.proto* from: https://blog.csdn.net/qq_30614345/article/details/131860694*/flag.Parse()lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))if err != nil {log.Fatalf("failed to listen: %v", err)}rpcServer := grpc.NewServer()var helloSever HelloServerpb.RegisterHelloServer(rpcServer, &helloSever)log.Printf("server listening at %v", lis.Addr())if err := rpcServer.Serve(lis); err != nil {log.Fatalf("failed to serve: %v", err)}
}

pb.RegisterHelloServer(rpcServer, &helloSever) 的源码:

// 下面的代码来自第2步生产的 hello.pb.go
func RegisterHelloServer(s *grpc.Server, srv HelloServer) {s.RegisterService(&_Hello_serviceDesc, srv)  ---------告诉 rpcServer 什么请求由谁处理;作用和普通 web server 的路由一样
}func _Hello_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {/* 第一个参数 srv 猜测会在 rpcServer 收到请求后,把 s.RegisterService(&_Hello_serviceDesc, srv)  的第二个参数传过来 */in := new(HelloRequest)if err := dec(in); err != nil {return nil, err}if interceptor == nil {return srv.(HelloServer).SayHello(ctx, in)}info := &grpc.UnaryServerInfo{Server:     srv,FullMethod: "/mypackage.Hello/SayHello",}handler := func(ctx context.Context, req interface{}) (interface{}, error) {return srv.(HelloServer).SayHello(ctx, req.(*HelloRequest))}return interceptor(ctx, in, info, handler)
}var _Hello_serviceDesc = grpc.ServiceDesc{ServiceName: "mypackage.Hello",HandlerType: (*HelloServer)(nil),Methods: []grpc.MethodDesc{{MethodName: "SayHello",Handler:    _Hello_SayHello_Handler,},},Streams:  []grpc.StreamDesc{},Metadata: "hello.proto",
}

客户端代码

package mainimport (pb "awesomeProject/libadv/grpcdbg/hello""context""flag""google.golang.org/grpc/credentials/insecure""log""time"
)
import "google.golang.org/grpc"var defaultName = "world"
var (//addr = flag.String("addr", "localhost:50052", "the address to connect to")addr = flag.String("addr", "127.0.0.1:50052", "the address to connect to")name = flag.String("name", defaultName, "Name to greet")
)func main() {flag.Parse()// Set up a connection to the server.conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {log.Fatalf("did not connect: %v", err)}defer conn.Close()helloClient := pb.NewHelloClient(conn)// Contact the server and print out its response.ctx, cancel := context.WithTimeout(context.Background(), time.Second)defer cancel()request := pb.HelloRequest{Name: *name, Age: "22"}r, err := helloClient.SayHello(ctx, &request)if err != nil {log.Fatalf("could not greet: %v", err)}log.Printf("Greeting: %s", r.GetMessage())
}

相关文章:

grpc 快速入门

gRPC 是一个现代的远程过程调用(RPC)框架,由 Google 开发。它使用 HTTP/2 作为传输协议,并采用 Protocol Buffers(protobuf)作为接口描述语言(IDL)。gRPC 提供高效的通信、语言无关性…...

layui 实现 城市联动

<div class"layuimini-container"><form id"app-form" class"layui-form layuimini-form"><div class"layui-form-item"><label class"layui-form-label">标题</label><div class"la…...

C++11标准模板(STL)- 常用数学函数 - 分类及比较 - 对给定的浮点值分类(std::fpclassify)

常用数学函数 对给定的浮点值分类 std::fpclassify 定义于头文件 <math.h> #define fpclassify(arg) /* implementation defined */ (C99 起) 归类浮点值 arg 到下列类别中&#xff1a;零、非正规、正规、无穷大、 NaN 或实现定义类别。该宏返回整数值。 忽略 FLT_EV…...

报错:npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。

报错场景 使用npm run dev 报错 npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1&#xff0c;因为在此系统上禁止运行脚本。有关详细信息&#xff0c;请参阅 https:/go.microsoft.com/fwlink/?LinkID135170 中的 about_Execution_Policies。 所在位置 行:1 字符: 1 npm…...

OpenCV基本操作(python开发)——(7)实现图像校正

OpenCV基本操作&#xff08;python开发&#xff09;——&#xff08;1&#xff09; 读取图像、保存图像 OpenCV基本操作&#xff08;python开发&#xff09;——&#xff08;2&#xff09;图像色彩操作 OpenCV基本操作&#xff08;python开发&#xff09;——&#xff08;3&…...

[项目] C++基于多设计模式下的同步异步日志系统

[项目] C基于多设计模式下的同步&异步日志系统 文章目录 [项目] C基于多设计模式下的同步&异步日志系统日志系统1、项目介绍2、开发环境3、核心技术4、日志系统介绍4.1 日志系统的价值4.2 日志系统技术实现4.2.1 同步写日志4.2.2 异步写日志 5、相关技术知识5.1 不定参…...

Vue常用的修饰符有哪些?

修饰符&#xff08;Modifiers&#xff09;是用于指定以特殊方式绑定或处理Vue事件或指令的特殊符号。 事件修饰符 .stop: 阻止时间继续传播&#xff0c;相当于调用event.stopPropagation() .prevent: 阻止默认事件&#xff0c;相当于调用event.preventDefault() .capture: 使…...

AnatoMask的分层图像编码器-解码器

方法思想 采用多尺度编码器-解码器主干&#xff1a; 在编码器中&#xff0c;把CT图像分解成不同大小的图像块&#xff0c;从这些图像块中提取特征在解码器中&#xff0c;重建被掩盖图像时&#xff0c;考虑图像块的空间关系 输入D&#xff08;深度Depth&#xff09;张H&#x…...

面向对象编程的核心特性:封装、继承、多态与抽象

封装&#xff08;Encapsulation&#xff09;&#xff1a; 定义&#xff1a;封装是面向对象编程中的一个基本原则&#xff0c;它指的是将对象的状态&#xff08;属性&#xff09;和行为&#xff08;方法&#xff09;捆绑在一起&#xff0c;并对外隐藏对象的内部实现细节&#xf…...

ubuntu openmpi安装(超简单)

openmpi安装 apt update apt install openmpi-bin openmpi-common libopenmpi-dev安装到此完毕 测试一下&#xff0c;success !...

Python中的SQL数据库管理:SQLAlchemy教程

Python中的SQL数据库管理&#xff1a;SQLAlchemy教程 在Python应用程序中&#xff0c;操作数据库是常见的需求之一。而 SQLAlchemy 是一个功能强大的数据库管理库&#xff0c;它提供了Pythonic的接口来管理和查询SQL数据库。SQLAlchemy 兼具 ORM&#xff08;对象关系映射&…...

LeetCode --- 421周赛

题目列表 3334. 数组的最大因子得分 3335. 字符串转换后的长度 I 3336. 最大公约数相等的子序列数量 3337. 字符串转换后的长度 II 一、数组的最大因子得分 数据范围足够小&#xff0c;可以用暴力枚举移除的数字&#xff0c;得到答案&#xff0c;时间复杂度为O(n^2)&#…...

简单了解前缀树/字典树(Trie树)C++代码

介绍Trie树 Trie&#xff08;发音类似 "try"&#xff09;或者说 前缀树 是一种树形数据结构&#xff0c;用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景&#xff0c;例如自动补全和拼写检查。 前缀树也有一些其它的名称&#xff1a;字典…...

ubuntu安装与配置Nginx(2)

1. 配置 Nginx Nginx 的配置文件通常位于 /etc/nginx/nginx.conf&#xff0c;而虚拟主机的配置文件通常在 /etc/nginx/sites-available/ 和 /etc/nginx/sites-enabled/ 目录中。 在/etc/nginx/conf.d目录下新建xx.conf文件&#xff0c;配置文件&#xff0c; nginx -t 检查语法…...

Linux环境下Mongodb部署

文章目录 一、系统环境二、MongoDb安装添加MongoDB官方库安装MongoDB配置MongoDB 三、MongoDB常见操作四、MongoDB用户管理创建用户修改密码删除用户 五、启用安全控制六、备份与还原1. 备份2. 恢复 七、外部工具连接MongoDB 一、系统环境 CentOS Stream 9 64bit 二、MongoD…...

(九)JavaWeb后端开发——Servlet

目录 1.Servlet由来 2.Servlet快速入门 3.Servlet执行原理 4.Servlet生命周期 1.Servlet由来 在JaveEE API文档中对Servlet的描述是&#xff1a;可以运行在服务器端的微小程序&#xff0c;但是实际上&#xff0c;Servlet就是一个接口&#xff0c;定义了Java类被浏览器访问…...

【零售和消费品&家居用品】家庭门窗开闭状态安全监控系统源码&数据集全套:改进yolo11-DCNV2

改进yolo11-GhostDynamicConv等200全套创新点大全&#xff1a;家庭门窗开闭状态安全监控系统源码&#xff06;数据集全套 1.图片效果展示 项目来源 人工智能促进会 2024.11.01 注意&#xff1a;由于项目一直在更新迭代&#xff0c;上面“1.图片效果展示”和“2.视频效果展示”…...

【JavaScript】axios 二次封装拦截器(接口、实例、全局)

学习 coderwhy 老师结合 ts 二次封装 axios 目录结构 config config\index.ts // export const BASE_URL "http://codercba.com:9002"; export const TIME_OUT 10000;// 1. 根据环境变量区分接口地址 // let BASE_URL: string; // if (process.env.NODE_ENV &qu…...

Linux_02 Linux常用软件——vi、vim

vi编辑器有三种主要模式&#xff0c;每种模式的功能和用途不同&#xff1a; 一、命令模式 (Command Mode)&#xff1a; - 启动 vi 时默认进入此模式。 - 你可以在此模式下移动光标&#xff0c;输入各种命令&#xff08;如删除、复制、粘贴等&#xff09;。 yy&#xff1a;…...

C++代码优化--要求或禁止在堆中产生对象

目录 1.引言 2.栈与堆区别 2.1. 栈&#xff08;Stack&#xff09; 2.2. 堆&#xff08;Heap&#xff09; 3.限制在堆上分配内存的好处 4.对象在栈上分配内存的方法 4.1. 使用RAII&#xff08;资源获取即初始化&#xff09; 4.2. 避免使用new和delete 4.3. 限制对象的生…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天&#xff0c;深度学习与大模型技术已成为推动行业变革的核心驱动力&#xff0c;而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心&#xff0c;系统性地呈现了两部深度技术著作的精华&#xff1a;…...

恶补电源:1.电桥

一、元器件的选择 搜索并选择电桥&#xff0c;再multisim中选择FWB&#xff0c;就有各种型号的电桥: 电桥是用来干嘛的呢&#xff1f; 它是一个由四个二极管搭成的“桥梁”形状的电路&#xff0c;用来把交流电&#xff08;AC&#xff09;变成直流电&#xff08;DC&#xff09;。…...

Linux 内存管理调试分析:ftrace、perf、crash 的系统化使用

Linux 内存管理调试分析&#xff1a;ftrace、perf、crash 的系统化使用 Linux 内核内存管理是构成整个内核性能和系统稳定性的基础&#xff0c;但这一子系统结构复杂&#xff0c;常常有设置失败、性能展示不良、OOM 杀进程等问题。要分析这些问题&#xff0c;需要一套工具化、…...