golang grpc初体验

grpc 是一个高性能、开源和通用的 RPC 框架,面向服务端和移动端,基于 HTTP/2 设计。目前支持c、java和go,分别是grpc、grpc-java、grpc-go,目前c版本支持c、c++、node.js、ruby、python、objective-c、php和c#。grpc官网 grpc-go
在这里插入图片描述
ProtoBuf(全称Protocol Buffer)是数据结构序列化和反序列化框架,ProtoBuf是Google推出的一款轻量高效的数据化数据存储格式,性能比json、xml强,ProtoBuf经历了ProtoBuf2和ProtoBuf3,ProtoBuf3比ProtoBuf简化了很多,目前主流的是ProtoBuf3.
优点:
1.性能:压缩性好、序列化和反序列化快(比xml和json快2-100倍)、传输速度快
2.便捷性:使用简单(自动生成序列化和反序列化代码)、维护成本低(只支持proto文件)、向后兼容(不必破坏旧格式)、加密型号
3.跨语言:跨平台、支持各种主流语言
缺点:
1.通用性差:json可以任何语言都支持,但是protobuf需要专门的解析库
2.自解释性差:只有通过proto文件才能了解数据结构
protoBuf安装并配置环境变量官网
1.编辑环境变量文件‌:vim ~/.zshrc
‌2.添加环境变量‌:

export PATH="$PATH:/usr/local/go/src/GolangStudy/protoc-28.2-osx-x86_64/bin"

3.使配置生效‌:保存并关闭编辑器后,在终端中输入source ~/.zshrc
命令,使更改生效。
4.验证

 protoc --version

安装protoBuf的go依赖包

go get github.com/golang/protobuf/protoc-gen-go

helloworld.proto

syntax = "proto3";// 生成 proto 文件所在包路径
package protos;
// 影响go文件生成位置和包名
option go_package = "GolangStudy/Introduction/grpc/protos";
message HelloRquest{string name=1;//1是编号不是值
}

项目目录结构
在这里插入图片描述
转换命令(第一种命令使用grpc,会比第二种多很多)

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative helloworld.proto 
protoc --go_out=/usr/local/go/src/GolangStudy/GolangStudy --proto_path=/usr/local/go/src/GolangStudy/GolangStudy/Introduction/grpc/protos --go_opt=module=GolangStudy helloworld.proto

调用并比较跟json格式的区别

package mainimport ("GolangStudy/Introduction/grpc/protos""encoding/json""fmt""github.com/golang/protobuf/proto"
)type Hello struct {Name string `json:"name"`
}func main() {req := protos.HelloRquest{Name: "bobby",}jsonStruct := Hello{Name: "bobby"}jsonRsp, _ := json.Marshal(jsonStruct)fmt.Println(len(string(jsonRsp)))rsp, _ := proto.Marshal(&req)fmt.Println(len(string(rsp)))
}

json长度是15,而protobuf长度是7

grpc四种数据流

简单模式(simple rpc):客户端发起一次请求,服务端响应一个数据
服务端数据流模式(server-side streaming rpc):客户端发起一次请求,服务端返回一段连续的数据流。(客户端向服务端发送一个股票代码,服务端就把该股票的实时数据源源不断的返回给客户端)
客户端数据流模式(client-side streaming rpc):客户端源源不断的项向服务端发送数据流,而在发送结束后,由服务器返回一个响应(物流网终端向服务器报送数据)
双向数据流模式(bidirectional streaming rpc):客户端和服务端都可以向双方发送数据流,双方的数据可以同时互相发送,可以实现实时交互(聊天机器人)

grpc简单模式

目录结构
在这里插入图片描述

proto代码

syntax = "proto3";// 生成proto文件所在包路径
package protos;
option go_package = ".;proto";
// 影响go文件生成位置和包名
service Greeter{rpc SayHello(HelloRquest)returns(HelloReply);//hello接口
}
message HelloRquest{string name=1;//1是编号不是值
}
message HelloReply{string message=1;
}

生成go文件

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative helloworld.proto

使用接口删除这一行(可能是生成方式的问题)
在这里插入图片描述
server端

package mainimport ("GolangStudy/Introduction/grpc/example2/proto""context""net""google.golang.org/grpc"
)type Server struct {
}func (s *Server) SayHello(ctx context.Context, request *proto.HelloRquest) (*proto.HelloReply, error) {return &proto.HelloReply{Message: "helo" + request.Name,}, nil
}
func main() {g := grpc.NewServer()proto.RegisterGreeterServer(g, &Server{})lis, err := net.Listen("tcp", "0.0.0.0:8080")if err != nil {panic("failed to listen:" + err.Error())}err = g.Serve(lis)if err != nil {panic("failed to start ")}
}

client端

package mainimport ("GolangStudy/Introduction/grpc/example2/proto""context""fmt""google.golang.org/grpc"
)func main() {conn, err := grpc.Dial("127.0.0.1:8080", grpc.WithInsecure())if err != nil {panic(err)}defer conn.Close()c := proto.NewGreeterClient(conn)r, err := c.SayHello(context.Background(), &proto.HelloRquest{Name: "bobby",})if err != nil {panic(err)}fmt.Println(r.Message)
}

grpc流模式

proto

syntax = "proto3";// 生成proto文件所在包路径
package protos;
option go_package = ".;proto";
// 影响go文件生成位置和包名
service Greeter{rpc GetStream(StreamReqData)returns(stream SteramResData);//服务端流模式rpc PostStream(stream StreamReqData)returns(stream SteramResData);//客户端流模式rpc AllStream(stream StreamReqData)returns(stream SteramResData);//双向流模式
}
message StreamReqData{string data=1;
}
message SteramResData{string data=1;
}

生成go文件

 protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative stream.proto

删除
在这里插入图片描述
server

package mainimport ("GolangStudy/Introduction/grpc/stream_grpc_test/proto""fmt""net""sync""time""google.golang.org/grpc"
)const PORT = ":50052"type server struct {
}func (s *server) GetStream(req *proto.StreamReqData, res proto.Greeter_GetStreamServer) error {i := 0for {i++_ = res.Send(&proto.SteramResData{Data: fmt.Sprintf("%v", time.Now().Unix()),})time.Sleep(time.Second)if i > 10 {break}}return nil
}
func (s *server) PostStream(cliStr proto.Greeter_PostStreamServer) error {for {if a, err := cliStr.Recv(); err != nil {fmt.Println(err)break} else {fmt.Println(a.Data)}}return nil
}
func (s *server) AllStream(allStr proto.Greeter_AllStreamServer) error {wg := sync.WaitGroup{}wg.Add(2)go func() {defer wg.Done()for {data, _ := allStr.Recv()fmt.Println("收到客户端消息:" + data.Data)}}()go func() {defer wg.Done()for {allStr.Send(&proto.SteramResData{Data: "我是服务器",})time.Sleep(time.Second)}}()wg.Wait()return nil
}
func main() {lis, err := net.Listen("tcp", PORT)if err != nil {panic(err)}s := grpc.NewServer()proto.RegisterGreeterServer(s, &server{})err = s.Serve(lis)if err != nil {panic("failed to start ")}
}

client

package mainimport ("GolangStudy/Introduction/grpc/stream_grpc_test/proto""context""fmt""sync""time""google.golang.org/grpc"
)func main() {conn, err := grpc.Dial("127.0.0.1:50052", grpc.WithInsecure())if err != nil {panic(err)}defer conn.Close()//服务端流模式// c := proto.NewGreeterClient(conn)// res, _ := c.GetStream(context.Background(), &proto.StreamReqData{Data: "mooc"})// for {// 	a, err := res.Recv() //socket编程send recv// 	if err != nil {// 		fmt.Println(err)// 		break// 	}// 	fmt.Println(a)// }// //客户端流模式// c := proto.NewGreeterClient(conn)// putS, _ := c.PostStream(context.Background())// i := 0// for {// 	i++// 	_ = putS.Send(&proto.StreamReqData{// 		Data: fmt.Sprintf("mooc%d", i),// 	})// 	time.Sleep(time.Second)// 	if i > 10 {// 		break// 	}// }//双向流模式c := proto.NewGreeterClient(conn)allStr, _ := c.AllStream(context.Background())wg := sync.WaitGroup{}wg.Add(2)go func() {defer wg.Done()for {data, _ := allStr.Recv()fmt.Println("收到服务器消息:" + data.Data)}}()go func() {defer wg.Done()for {allStr.Send(&proto.StreamReqData{Data: "我是客户端",})time.Sleep(time.Second)}}()wg.Wait()
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/443624.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【牛客刷题实战】BC120 争夺前五名

大家好,我是小卡皮巴拉 文章目录 目录 牛客题目: BC120 争夺前五名 题目描述 输入描述: 输出描述: 示例1 示例2 解题思路: 具体思路: 题目要点: 完整代码: 兄弟们共…

python爬虫 - 数据提取

🌈个人主页:https://blog.csdn.net/2401_86688088?typeblog 🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、数据类型及其对应的提取策略 (一)文本数据 &…

【设计模式】软件设计原则——开闭原则里氏替换单一职责

开闭原则内容引出 开闭原则 定义:一个软件实体,类,函数,模块;对扩展开放,对修改关闭。用抽象构建框架,用实现扩展细节。可以提高软件的可复用性和可维护性。 开发新功能时,尽量不修…

猿人学— 第一届第1题(解题思路附源码)

猿人学 — 第一届第1题(解题思路附源码) F12进入开发者工具—> 发现停止在debugger处 —> 右键点击Never pause here后下一步 翻页,抓包后发现请求携带page和m两个参数,page应该就是页数,m则需要逆向 依次查…

微服务中传递公共参数,在网关层header添加参数,各子微服务,openfeign,线程池等地方拿到网关传递过来的参数

需求: 网关层在header中添加参数,header-user_id1001,header-user_name小明 各个子微服务,可以通过openfeign,线程池等方式拿到上面的参数1 网关层 gateway添加需要传递的参数信息 import cn.hutool.core.net.URLEnco…

MySQL从0到1基础语法笔记(下)

博客主页:誓则盟约系列专栏:Java Web关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ 多表问题分析: 部门数据可以直接删除,然后还有部分员工…

Python对PDF文件的合并操作

在处理 PDF 文件时,合并多个 PDF 文件为一个单一文件或者将某个单一文件插入某个PDF文件是一个常见的需求。Python 提供了多种库来实现这一功能,其中 PyPDF2 是一个非常流行的选择。该库提供了简单易用的接口,包括 merge() 方法,可…

Linux系统和数据库常用的命令2

Linux系统和数据库常用的命令2 1、两台Linux机器ssh免密登录 client端登录server端需要免密,只需把公钥发送到server就可,会在server端生成一个authorized_keys文件 # 108机器上[rootclient ~]# ssh-keygen -t rsa // 非对称算法 Generating public/…

全闪 SDS 一体机提供 FC 能力承载医院核心业务

邹平市人民医院使用 X3000 SDS 一体机组建分布式存储集群,通过 FC 接口 与 VMware 集群连接,以全闪池承载核心业务,对象存储承载 PACS 数据,实现存储架构的升级改造。 “新医改”的不断推进,对医院的运营管理、服务质…

基础教程 | 用VuePress搭建一个简单的个人博客(附源码)

先附上自己个人博客页面:https://illusionno.github.io/ 源码也在这里:https://github.com/illusionno/my-blog (如果觉得有帮助,可以点颗star✨) 使用的主题是vuepress-theme-reco2.x,并在上面进行了一些调…

红外变电站分割数据集,标注为json格式,总共有5类,避雷器(289张),绝缘子(919张),电流互感器(413张),套管(161张),电压互感器(153张)

红外变电站分割数据集,标注为json格式,总共有5类 避雷器(289张),绝缘子(919张),电流互感器(413张),套管(161张)&#xff0…

【星汇极客】单片机竞赛之2024睿抗机器人大赛-火线速递赛道(持续更新)

前言 本人是一名嵌入式学习者,在大学期间也参加了不少的竞赛并获奖,包括:江苏省电子设计竞赛省一、睿抗机器人国二、中国高校智能机器人国二、嵌入式设计竞赛国三、光电设计竞赛国三、节能减排竞赛国三等。 暑假的时候参加了太多的比赛&#…

设备多久(60/50/40min)未上报,类似场景发送通知实现方案

场景描述 设备比较多,几十万甚至上百万,设备在时不时会上报消息。 用户可以设置设备60分钟、50分钟、40分钟、30分钟未上报数据,发送通知给用户,消息要及时可靠。 基本思路 思路: 由于设备在一直上报,如果…

Airtest脚本的重构与优化:提升测试效率和可读性

在自动化测试的工作里,编写高效且易于维护的测试脚本是一项挑战,尤其是在应对复杂的测试场景时。Airtest作为一款常用的自动化测试工具,它提供了丰富的API和灵活的脚本编写方式,帮助测试人员高效地开展UI自动化测试。然而&#xf…

Linux的环境与历史

目录 引言 1. Linux 背景介绍 2. 开源 3. 官网 4. 企业应用现状 5. 发行版本 6.见见猪跑 引言 在这个信息化时代,掌握一门操作系统技能显得尤为重要。Linux作为一款开源、稳定且功能强大的操作系统,不仅在服务器领域占据主导地位,也逐渐…

哈希表结构

哈希表结构:数组链表 案例一:HashSet集合的常见使用方法 package com.collection;import java.util.HashSet; import java.util.Iterator;/*** HashSet集合的使用* 存储结构:哈希表(数组链表红黑树)*/ public class Demo07 {public static v…

性能测试学习6:jmeter安装与基本配置/元件/线程组介绍

一.JDK安装 官网:https://www.oracle.com/ 二.Jmeter安装 官网:http://jmeter.apache.org/download_jmeter.cgi 下载zip包,zip后缀那个才是Windows系统的jmeter 三.Jmeter工作目录介绍 四.Jmeter功能 1)修改默认配置-汉化 2&am…

SapGUI For Windows捕获技术

一、SapGUI For Windows捕获技术 文章目录 一、SapGUI For Windows捕获技术SAP GUI:SAP NetWeaver Business Client:SAP Fiori:二.Sap的自动化配置SAP客户端配置三.Sap GUI自动化脚本四.Sap GUI自动化开发SAP GUI: SAP图形用户界面,是最常用的SAP前端界面。它是一个桌面应…

React(一) 认识React、熟悉类组件、JSX书写规范、嵌入变量表达式、绑定属性

文章目录 一、初始React1. React的基本认识2. Hello案例2.1 三个依赖2.2 渲染页面2.3 hello案例完整代码 二、类组件1. 封装类组件2. 组件里的数据3. 组件里的函数 (重点)4. 案例练习(1) 展示电影列表 三、JSX语法1. 认识JSX2. JSX书写规范及注释3. JSX嵌入变量作为子元素4. JS…

leetcode58:最后一个单词的长度

给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、不包含任何空格字符的最大 子字符串 。 示例 1: 输入:s "Hello World" 输出&#xff…