本文通过一个简单的例子来演示这4种类型的使用方法

案例代码:https://github.com/artfoxe6/grpc-sample-example

目录结构说明
├── calculator.proto # 定义 protobuf
├── client
│   ├── client.go # 客户端
│   ├── gencode
│   │   └── calculator.pb.go # protoc-gen-go中间件生成的go中间代码
│   ├── go.mod
│   └── go.sum
├── README.md
└── server
├── gencode
│   └── calculator.pb.go # 和上面一样
├── go.mod
├── go.sum
└── server.go # 服务端

client和server是两个完全独立的项目,所以protoc-gen-go生成的中间代码并没有公用,
而是放到各自单独的项目中,实际上两者内容是完全一样的

首先来看 calculator.proto

syntax = "proto3";

package rpc.calculator.test;

service Calculator {
//简单模式
rpc Add (TwoNum) returns (Response) {} //服务端流
rpc GetStream (TwoNum) returns (stream Response) {} //客户端流
rpc PutStream (stream OneNum) returns (Response) {} //双向流
rpc DoubleStream (stream TwoNum) returns (stream Response) {}
} message TwoNum {
int32 a = ;
int32 b = ;
}
message Response {
int32 c = ;
}
message OneNum{
int32 a = ;
}

这里定义了一个计算器服务,包含四个方法,这个四个方法分别演示了个RPC的四种服务类型
下面分别介绍这个四个方法是做什么的:
1. 客户端发送一个请求,包含两个数字,服务端是返回两个数字的和,这种最基本也是最常用的叫简单模式,
客户端发送一次,服务端返回一次,类似于接口请求

2. 客户端发送一个请求包含两个数字,服务端返回多次,第一次返回两数子和,第二次返回两数字乘,
这种叫服务端流模式,形象点说就是服务端向客户端搭了一根单向水管,可以不停的往客户端发送数据,
客户端不停的接收,直到接收到服务端发送的结束标记后停止接收
使用场景:
客户端请求一个数据列表,但是这个数据太多了,不可能一次返回,就可以利用这种模式,
服务端一次返回100条数据,前端一直接收处理

3. 客户端发送了很多次数据,数据是单个数字,服务端不停的接收数据,客户端发送结束后服务端返回所有数据的总和,
这就是客户端流模式,形象点说就是客户端往服务端搭了一个单向的水管,可以不停的往服务端发送数据,
服务端不停的接收,直到接收到客户端发送的结束标记后停止接收,处理完数据后一次性返回给客户端,

4. 客户端分多次发送数据给服务端,每次数据是两个数,服务端收到数据后多次返回给服务端,每次返回两个数之和,
客户端可以多次给服务端发送数据,服务端可以多次返回数据,这就是双向流模式,双方都需要同时处理发送数据和接收数据,
直到双方通道流关闭

利用calculator.proto生成go中间代码
在项目跟目录执行:

protoc -I ./ ./calculator.proto  --go_out=plugins=grpc:./server/gencode
protoc -I ./ ./calculator.proto --go_out=plugins=grpc:./client/gencode

分别在 ./server/gencode 和 ./client/gencode 两个目录生成了相同的go中间代码

有了中间代码后就可以编写服务端server.go了,由于篇幅限制,这里就不贴完整代码了,只对几个关键点做分析
导入中间代码

import pb "rpcserver/gencode"

定义了一个server,继承自 UnimplementedCalculatorServer

type server struct {
pb.UnimplementedCalculatorServer
}

这里有个技巧,打开calculator.pb.go你会发现,
UnimplementedCalculatorServer类已经"实现"了我们在calculator.proto中定义的所有个方法

type UnimplementedCalculatorServer struct {
}
func (*UnimplementedCalculatorServer) Add(ctx context.Context, req *TwoNum) (*Response, error) {
return nil, status.Errorf(codes.Unimplemented, "method Add not implemented")
}
....

如果你是新手,可以直接粘贴到server,稍作修改就可以了,函数体还是得自己写

func (s *server) Add(ctx context.Context, in *pb.TwoNum) (*pb.Response, error) {
return &pb.Response{C: in.A + in.B}, nil
}

其实gRPC的函数不多,定义也非常清晰,比如在写下面这个方法的时候

func (s *server) GetStream(in *pb.TwoNum, pipe pb.Calculator_GetStreamServer) error {
_ = pipe.Send(&pb.Response{C: in.A + in.B})
time.Sleep(time.Second * )
_ = pipe.Send(&pb.Response{C: in.A * in.B})
return nil
}

我也不知道有Send方法,如果用的GoLand,pipe点一下,能用的函数就出来了,就几个,一看就知道什么作用,
全程都没有用到godoc,当然我还是推荐你仔细看一下文档 https://godoc.org/google.golang.org/grpc

在来看一下客户端client.go
导入中间代码

import pb "rpcclient/gencode"

客户端就不说了,看一下代码吧

用一个例子说说gRPC的四种服务方法的更多相关文章

  1. java gRPC四种服务类型简单示例

    一.gRPC 简介 gRPC 是Go实现的:一个高性能,开源,将移动和HTTP/2放在首位通用的RPC框架.使用gRPC可以在客户端调用不同机器上的服务端的方法,而客户端和服务端的开发语言和 运行环境 ...

  2. gRPC学习之四:实战四类服务方法

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  3. C语言中返回字符串函数的四种实现方法 2015-05-17 15:00 23人阅读 评论(0) 收藏

    C语言中返回字符串函数的四种实现方法 分类: UNIX/LINUX C/C++ 2010-12-29 02:54 11954人阅读 评论(1) 收藏 举报 语言func存储 有四种方式: 1.使用堆空 ...

  4. C语言中返回字符串函数的四种实现方法

    转自C语言中返回字符串函数的四种实现方法 其实就是要返回一个有效的指针,尾部变量退出后就无效了. 有四种方式: 1.使用堆空间,返回申请的堆地址,注意释放 2.函数参数传递指针,返回该指针 3.返回函 ...

  5. Django的POST请求时因为开启防止csrf,报403错误,及四种解决方法

    Django默认开启防止csrf(跨站点请求伪造)攻击,在post请求时,没有上传 csrf字段,导致校验失败,报403错误 解决方法1: 注释掉此段代码,即可. 缺点:导致Django项目完全无法防 ...

  6. 百度地图和高德地图坐标系的互相转换 四种Sandcastle方法生成c#.net帮助类帮助文档 文档API生成神器SandCastle使用心得 ASP.NET Core

    百度地图和高德地图坐标系的互相转换   GPS.谷歌.百度.高德坐标相互转换 一.在进行地图开发过程中,我们一般能接触到以下三种类型的地图坐标系: 1.WGS-84原始坐标系,一般用国际GPS纪录仪记 ...

  7. AJPFX关于Java中运用数组的四种排序方法

    JAVA中在运用数组进行排序功能时,一般有四种方法:快速排序法.冒泡法.选择排序法.插入排序法.快速排序法主要是运用了Arrays中的一个方法Arrays.sort()实现.冒泡法是运用遍历数组进行比 ...

  8. javascript DOM和DOM操作的四种基本方法

    在了解了javascript的语言特性后,javascript真正大放光彩的地方来了——这就是javascript DOM Javascript DOM DOM(Document Object Mod ...

  9. c#数据四种执行方法(ExecuteNonQuery)-----转载

    c#数据四种执行方法(ExecuteNonQuery)   1.使用ExecuteReader()操作数据库 2.使用ExecuteNonQuery()操作数据库 3.使用ExecuteScalar( ...

随机推荐

  1. 《javascript高级程序设计》笔记:文档模式

    文档模式是用于指定浏览器使用什么样的标准来正确的显示网页,各个标准的解析存在着差异 文档类型的分类 文档模式大致分为三种类型: 混杂模式(quirks mode) 标准模式(standards mod ...

  2. 简单说 JavaScript中的tostring( ) 与 valueOf( )方法

    说明 所有的对象都继承有toString() 和 valueOf() 方法,对象到字符串,对象到数字的转换,会通过调用待转换对象的这两个方法中的一个来完成. 解释 toString( )方法的作用是: ...

  3. css 进度条的文字根据进度渐变

    需求 1.进度条里面的文字需要根据进度的长度而变化 原理 用两个一模一样的样式的 div 重叠起来 效果 字体开始为 蓝色,跟随进度条变为 白色 在线预览: https://jsfiddle.net/ ...

  4. Python正则表达式语法

    单个字符匹配 字符 匹配 . 匹配任意字符(除了\n) [...] 匹配字符集 \d/\D 匹配数字/非数字 \s/\S 匹配空白/非空白字符 \w/\W 匹配单词字符[a-zA-A0-9] In [ ...

  5. python3.6 单文件爬虫 断点续存 普通版 文件续存方式

    # 导入必备的包 # 本文爬取的是顶点小说中的完美世界为列.文中的aa.text,bb.text为自己创建的text文件 import requests from bs4 import Beautif ...

  6. Java 创建、编辑、删除Excel命名区域

    Excel命名区域,即对指定单元格区域进行命名,以便对单元格区域引用,如在公式运用中可以引用指定命名区域进行公式操作.在创建命名区域时,可针对整个工作簿来创建,即workbook.getNameRan ...

  7. React利用Antd的Form组件实现表单功能(转载)

    一.构造组件 1.表单一定会包含表单域,表单域可以是输入控件,标准表单域,标签,下拉菜单,文本域等. 这里先引用了封装的表单域 <Form.Item /> 2.使用Form.create处 ...

  8. 二、create-react-app自定义配置

    这里主要讲解添加less  和  实现Antd按需加载 首选需要执行npm run eject 暴露所有内建的配置 ,这是后面所有配置的基础,这个必须优先执行! 一.实现Antd按需加载 按需加载插件 ...

  9. MySQL数据备份及还原(一)

    关于删库跑路的事故现在已经屡见不鲜了,数据备份的必要性是企业数据管理极其重要的一项工作.关于数据备份.恢复也有很多场景及方法,本系列也会将主要的几种工具通过案例进行演示. 本系列将从逻辑备份及恢复开始 ...

  10. oracle中plsql练习-----在控制台输出1到100以内的素数。

    一.思路:首先需要知道素数的概念即质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数. 中心思想是,外循环所有的自然数,内循环折半查询,增加代码的速度,注意:从1开始,需要大于1,但是pl ...