IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> grpc 基本使用 -> 正文阅读

[网络协议]grpc 基本使用

grpc是由google开发的一款语言中立、平台中立、开源的RPC系统

在grpc中客户端应用可以像调用本地对象一样直接调用另一台不同机器上服务端应用的方法,使得很容易创建分布式应用和服务。与许多RPC系统类似,grpc也是定义一个服务,指定能够被远程调用的方法,在服务端实现该接口,并允许grpc服务器来处理客户端调用。客户端拥有像服务端一样方法的stub。

在这里插入图片描述

grpc允许定义四种服务方法

  • 单项RPC,即客户端发送一个请求给服务端,然后从服务端获取一个应答,就像一次普通的函数调用
  • 服务端流式RPC,客户端发送一个请求给服务端,可获取一个数据流给客户端读取消息
  • 客户端流式RPC,即用客户端提供的一个数据流写入并发送一系列消息给服务端,一旦客户端完成消息写入,就等待服务端读取这些消息并应答
  • 双向流式 RPC,即两边都可以分别通过一个读写数据流来发送一系列消息。这两个数据流操作是相互独立的,所以客户端和服务端能按其希望的任意顺序读写,例如:服务端可以在写应答前等待所有的客户端消息,或者它可以先读一个消息再写一个消息,或者是读写相结合的其他方式。每个数据流里消息的顺序会被保持。

以下以一个简单的获取产品的场景来演示grpc的使用

使用protoc buffer定义服务

protoBuffer主要编写相应的数据结构以及接口方法定义

syntax="proto3";
package pd;

option go_package="/pd";

// 因为rpc方法参数不能为空,所以定义一个空message
message empty {
}

// 产品
message Prod {
	string id = 1;
	string name = 2;
}

// 因为所有参数都只能为message类型,所以对于prodId还是要定义为message
message ProdId {
	int64 val = 1;
}

产品服务定义如下

syntax="proto3";
package pd;

option go_package="/pd";

import "pd/common.proto";

service ProdInfo{
  rpc addProd(Prod) returns (ProdId);
  rpc getProd(ProdId) returns (Prod);
  // stream就是前文介绍的流
  rpc listProds(empty) returns (stream Prod);
  rpc listProdsByIds(stream ProdId) returns (stream Prod);
}

当我们运行protoc命令之后,就会为我们自动生成pb.go文件

# --go-grpc_out 为grpc插件,可以通过
protoc -I ../  --go-grpc_out=../  ../pd/prod.proto
protoc -I ../  --go_out=../  ../pd/common.proto

实现服务

以下是实现过程

import (
	"context"
	"io"
	"learn/grpc-demo/pd"
)

type prodServer struct {
	pd.UnsafeProdInfoServer
	prodMap map[int64]*pd.Prod
	index   int64
}

func (s *prodServer) GetProd(ctx context.Context, id *pd.ProdId) (*pd.Prod, error) {
	return s.prodMap[id.Val], nil
}

func (s *prodServer) ListProds(empty *pd.Empty, server pd.ProdInfo_ListProdsServer) error {
	for _, prod := range s.prodMap {
		if err := server.Send(prod); err != nil {
			return err
		}
	}

	return nil
}

func (s *prodServer) ListProdsByIds(server pd.ProdInfo_ListProdsByIdsServer) error {
	for {
		in, err := server.Recv()
		if err == io.EOF {
			return nil
		}
		if err != nil {
			return err
		}
		pid := in.Val
		if prod, ok := s.prodMap[pid]; ok {
			if err = server.Send(prod); err != nil {
				return err
			}
		}
	}
}

func (s *prodServer) AddProd(ctx context.Context, p *pd.Prod) (resp *pd.ProdId, err error) {
	s.prodMap[s.index] = p
	s.index++
	return &pd.ProdId{Val: s.index - 1}, nil
}

值得注意的是出现了一个很奇怪的pd.UnsafeProdInfoServer,在新版protoc-gen-grpc-go编译器中,Server实现必须向前兼容

当然也可以通过以下命令不生成向前兼容service

protoc --go-grpc_out=require_unimplemented_servers=false:.

编写服务端和客户端

服务端监听

	conn,err:=net.Listen("tcp",":8888")
	if err != nil {
		t.Fatalf("fail to listen for %s",err)
	}

	s :=grpc.NewServer()
	pd.RegisterProdInfoServer(s,&prodServer{
		prodMap: make(map[int64]*pd.Prod),
		index: 0,
	})

	err=s.Serve(conn)
	if err != nil {
		t.Fatal("fail to serve")
	}

客户端请求,并可以通过grpc.WithInsecure()取消认证

	conn,err:=grpc.Dial(":8888",grpc.WithInsecure())
	if err != nil {
		t.Fatal("fail to conn server")
	}
	defer conn.Close()

	c:=pd.NewProdInfoClient(conn)
	pid,err:=c.AddProd(context.Background(),&pd.Prod{
		Id:   "x",
		Name: "we",
	})
	if err != nil {
		t.Fatal("add prod failed")
	}

	t.Logf("add prod %d",pid.Val)

Ref

  1. https://doc.oschina.net/grpc?t=58008
  2. https://blog.gopheracademy.com/advent-2017/go-grpc-beyond-basics/
  3. https://grpc.io/docs/guides/auth/
  4. https://shijuvar.medium.com/writing-grpc-interceptors-in-go-bf3e7671fe48
  5. https://stackoverflow.com/questions/65079032/grpc-with-mustembedunimplemented-method
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章           查看所有文章
加:2022-05-21 19:17:01  更:2022-05-21 19:18:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:40:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码