go grpc实战

2023-11-04

go rpc实战

什么是rpc以及rpc的原理就不加以阐述了,wiki-rpc对其进行了说明。本文 以登录过程为例,使用go作为开发语言,使用grpc库实现了登录接口。具体过程及代码如下所示。

环境准备

  1. app的同级目录创建appGoPath目录,在golandFile->Settings中配置GOPATHappGoPath目录所在路径,然后执行下列命令准备grpc环境
    go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
    go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
    
  2. 创建目录:app/cmd/componentTest/pb,存放登录相关的rpc相关的文件
  3. pb目录下创建登录服务的grpc服务文件login.proto
    syntax = "proto3";
    
    package login;
    
    option go_package = "../pb";
    
    message LoginRequest{
    string username=1;
    string password=2;
    }
    
    message LoginResponse{
    int32 code=1;
    string msg=2;
    }
    
    service LoginService{
    rpc Login(LoginRequest)returns(LoginResponse);
    }
    
  4. pb目录下创建build.sh文件,增加如下内容
    protoc --go_out=. --go_opt=paths=source_relative \
        --go-grpc_out=require_unimplemented_servers=false:. --go-grpc_opt=paths=source_relative \
        login.proto
    

    require_unimplemented_servers=false作用: 在LoginServiceServer中不生成mustEmbedUnimplementedLoginServiceServer接口

  5. pb目录所在路径下执行build.sh文件,会自动生成以下两个文件
    • login.pb.go
    • login_grpc.pb.go
  6. 生成的上述两个文件在goland中提示Cannot resolve symbol 'protobuf',使用golandSync dependency of机制进行同步即可
  7. app/cmd/componentTest目录下创建test目录,创建rpc_login_test.go文件,添加代码如下:
    package test
    
    import (
       "context"
       "google.golang.org/grpc"
       "google.golang.org/grpc/credentials/insecure"
       "log"
       "app/cmd/componentTest/pb"
       "net"
       "os"
       "os/signal"
       "syscall"
       "testing"
       "time"
    )
    
    type LoginServiceServerImpl struct{}
    
    func (l LoginServiceServerImpl) Login(ctx context.Context, request *pb.LoginRequest) (*pb.LoginResponse, error) {
       username := request.Username
       password := request.Password
       if username == "leebai" && password == "123456" {
          return &pb.LoginResponse{
             Code: 200,
             Msg:  "success",
          }, nil
       } else {
          return &pb.LoginResponse{
             Code: 201,
             Msg:  "fail",
          }, nil
       }
    }
    
    func StartRpcServer() {
       s := grpc.NewServer()
       pb.RegisterLoginServiceServer(s, new(LoginServiceServerImpl))
    
       port := ":8081"
       listener, err := net.Listen("tcp", port)
       if err != nil {
          log.Printf("listen port %s failed,err=%v\n", port, err)
       }
    
       s.Serve(listener)
    }
    
    // TestRpcLoginService 启动Rpc登录服务
    func TestRpcLoginService(t *testing.T) {
       go StartRpcServer()
    
       ch := make(chan os.Signal, 1)
       signal.Notify(ch, os.Interrupt, syscall.SIGTERM)
       exitCode := <-ch
       log.Printf("Exit Code:%v", exitCode)
    }
    
    // TestRpcClientLogin Rpc登录客户端,连接启动的Rpc登录服务,发送请求,获取响应
    func TestRpcClientLogin(t *testing.T) {
       targetHost := "localhost:8081"
       conn, err := grpc.Dial(targetHost, grpc.WithTransportCredentials(insecure.NewCredentials()))
       if err != nil {
          log.Printf("Dial %s failed,err=%v\n", targetHost, err)
       }
       defer conn.Close()
    
       // 构建一次用户名和密码匹配的rpc请求
       c := pb.NewLoginServiceClient(conn)
       t1 := time.Now()
       rpcReply, err := c.Login(context.Background(), &pb.LoginRequest{
          Username: "leebai",
          Password: "123456",
       })
       log.Printf("spend time:%v", time.Now().Sub(t1).Milliseconds())
       if err != nil {
          log.Printf("login failed,err=%v\n", err)
       } else {
          log.Printf("login response: %v\n", rpcReply)
       }
    
        构建一次用户名和密码不匹配的rpc请求
       //c2 := pb.NewLoginServiceClient(conn)
       //rpcReply, err = c2.Login(context.Background(), &pb.LoginRequest{
       //	Username: "zhangsan",
       //	Password: "123456",
       //})
       //if err != nil {
       //	log.Printf("login failed,err=%v\n", err)
       //} else {
       //	log.Printf("login response: %v\n", rpcReply)
       //}
    }
    

    以上func (l LoginServiceServerImpl) Login(ctx context.Context, request *pb.LoginRequest) (*pb.LoginResponse, error)
    需要实现login_grpc.pb.go中的接口type LoginServiceServer interface

  8. 先运行TestRpcLoginService方法启动rpc服务程序
  9. 再运行TestRpcClientLogin方法启动rpc客户端程序,向启动的rpc服务程序发起一次rpc调用,结果如下所示:
    === RUN   TestRpcClientLogin
    2023/05/05 14:15:08 spend time:11
    2023/05/05 14:15:08 login response: code:200 msg:"success"
    --- PASS: TestRpcClientLogin (0.03s)
    PASS
    
  10. 至此就完成了一个登录请求的远程rpc服务调用
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

go grpc实战 的相关文章

  • 如何从 golang fyne 容器中删除对象

    我正在开发 GUI 应用程序 需要动态添加和删除 gui 元素 我想知道是否有办法从 golang fyne 容器中删除元素 在下面的示例代码中 我创建了容器并动态添加元素 现在我希望能够删除这些元素而不是隐藏它们 我尝试的一个 解决方案
  • 防止使用 golang 服务器访问文件夹中的文件

    我在 golang 中有一个服务器可以处理这样的文件夹路径 fs http FileServer http Dir assets http Handle Images fs http ListenAndServe 8000 nil 但在这个
  • 如何使用 go web 服务器提供静态 html 文件?

    如何使用 go web 服务器提供 index html 或其他静态 HTML 文件 我只想要一个基本的静态 HTML 文件 例如一篇文章 我可以从 Go Web 服务器提供该文件 HTML 应该可以在 go 程序之外进行修改 就像使用 H
  • Go 编程 - 使用指针绕过访问权限

    假设我的项目有以下层次结构 fragment fragment go main go 并且在fragment go我有以下代码 只有一个 getter 没有 setter package fragment type Fragment str
  • 从 Go Slice 中选择一个随机值

    情况 我有一些值 需要从中随机选择一个值 然后我想将它与固定字符串连接起来 到目前为止 这是我的代码 func main create the reasons slice and append reasons to it reasons m
  • 如何使用 golang 和 mgo 库在 mongodb 中创建文本索引?

    我正在尝试对集合进行全文搜索 但为了做到这一点 我需要创建一个文本索引 http docs mongodb org manual tutorial create text index on multiple fields http docs
  • 如何自定义解析错误的 HTTP 400 响应?

    我编写了一个 REST API 服务 要求所有响应均为 JSON 但是 当 Go HTTP 请求解析器遇到错误时 它会返回 400 作为纯文本响应 而不会调用我的处理程序 例子 gt curl i H Authorization Basic
  • vscode 中的调试不会在断点处停止,调试器启动时显示“无法找到文件...”

    乌班图 vscode 1 62 1 去1 17 3 vscode go 扩展 v0 29 0 深入研究 v1 7 1 我是 vscode 和 Go 的新手 我有多年在 Eclipse 中调试 Java 应用程序的经验 我构建了一个小型多模块
  • 使用 crypto/ssh 的 golang scp 文件

    我正在尝试通过 ssh 下载远程文件 以下方法在 shell 上运行良好 ssh hostname tar cz opt local folder gt folder tar gz 然而 golang 上的相同方法在输出工件大小方面存在一些
  • 取消用户特定的 goroutine [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个应用程序 网络应用程序 允许用户使用 twitter oauth 登录并提供自动推文删除功能 用户登录到 Web 应用程序后
  • 共享来自单独命令/进程的属性

    我提供带有多个命令和子命令的命令行工具 我使用cobra https github com spf13 cobra命令行 我有两个单独的命令首先是前提条件e 给其他人 例如第一个命令是通过创建临时文件夹并验证某些文件来首选环境 第二个命令应
  • Go 中的 WebP 编码器/解码器

    是否有一个完整的 WebP 编码器和解码器与当前每周 或可分叉 兼容 它的速度与标准 png 相当吗 这个人在 GitHub 上有一个包 其中包含 WebP 的编码器和解码器 https github com chai2010 webp h
  • Golang 按位运算以及一般字节操作

    我有一些 C 代码 可以对字节执行一些按位运算 我正在尝试在 golang 中做同样的事情 但遇到了困难 C 中的示例 byte a c byte data int j c data j c byte c j c a c 0xFF c 0x
  • 我们如何在 Golang 中组合多个错误字符串?

    我是 golang 新手 我的应用程序需要在循环中返回多个错误 稍后需要组合并作为单个错误字符串返回 我无法使用字符串函数来组合错误消息 在返回之前可以使用什么方法将这些错误合并为一个错误 package main import fmt s
  • 为什么我的 SQL 占位符没有被替换(使用 Go pq)?

    根据文档 我正在这样做 var thingname string asdf var id int err database QueryRow SELECT id from things where thing thingname Scan
  • Golang 基础知识 struct 和 new() 关键字

    我正在学习 golang 当我阅读描述结构的章节时 我遇到了初始化结构的不同方法 p1 passport var p2 passport p3 passport Photo make byte 0 0 Name Scott Surname
  • 在 IntelliJ IDEA 中运行。多个文件和错误未定义:数据

    我想使用 IntelliJ IDE 社区版编写代码GO Go语言 我安装了正确的插件 并安装了构建应用程序所需的所有工具 我的应用程序包含以下两个文件 每个都在目录中 事件服务器 Main go Data go 如果我想使用 Run Ctl
  • 在 Go 中使用电子邮件地址创建证书签名请求 (CSR)

    我尝试使用 crypto x509 包生成 CSR 但没有找到将 emailAddress 字段添加到其主题中的方法 根据文档证书申请 http golang org pkg crypto x509 CertificateRequest结构
  • 如何从非英语字符串解析go中的月份

    我想将以下字符串解析为 go 中的日期 This item will be released on March 9 2014 我跟着this https stackoverflow com questions 14106541 go par
  • Go 的范围不能超过 (类型接口 {})

    我正处于尝试将我的注意力集中在 Go 上的婴儿阶段 目前 我正在模拟一个 API 请求 该请求返回包含对象数组的 JSON 格式的字符串 我试图找出迭代每个记录并访问每个字段的最合适的方法 最终 每个字段都将写入 Excel 电子表格 但现

随机推荐

  • 嵌入式arm Linux下使用BusyBox的crond服务的定时任务方法 之前的程序有问题tcp经常中断,程序还在,linux端口还在占用10777,tcp能连一会就断了,暂时用定时重启

    keepalive sh 守护及定时任务脚本 bin sh 定时每天1 30重启应用程序 先关闭crond killall 9 crond 创建目录 默认是没有的 mkdir p var spool cron crontabs 编辑定时任务
  • 分苹果

    描述 把M个同样的苹果放在N个同样的盘子里 允许有的盘子空着不放 问共有多少种不同的分法 注意 假如有3个盘子7个苹果 5 1 1和1 5 1 是同一种分法 输入 t 表示测试组数 t lt 10 然后t行 每行包含两个数M N 1 lt
  • Qt信号槽连接失败的两种情况

    Qt的信号槽在平常工作中用的很多 今天在调试程序的时候 出现了两种链接失败的情况 链接代码如下 bool b connect this SIGNAL signalTest std string unsigned int SLOT onTes
  • C++ 类和对象-封装

    C 面向对象的三大特征为 封装 继承 多态 C 认为所有事物都能成为对象 对象上有其属性和行为 例如 人可以作为对象 属性有姓名 年龄 身高 行为有走 跑 跳 车可以作为对象 属性有轮胎 车灯 方向盘 行为有载人 放音乐 封装 属性和行为作
  • Linux循环

    for循环迭代 for var in list do commands done 或 for C语言格式 以上为for循环格式 其中的list可以为字符串 通过IFS分隔 也可以为序列 序列生成方式如下 1 5 a z A Z while循
  • Android4.0 中关于内外置sd卡——读写及权限问题

    在android4 0源码出来以后 关于sd卡问题似乎没有解决好 起码上层api中没有体现到位 其实在framework层中有相应的类去获得内外置sd卡信息 是否可读写的权限 在2 x的版本中 在manifest中配置的权限android
  • Android系统屏保功能开发(Android10)

    Android系统屏保功能开发 1 AndroidManifest xml 文件配置 需要先配置为系统应用
  • IPSec ***不通时的故障处理方法

    IPSec 不通 介绍了IPSec 不通时的故障处理方法 现象描述 如图1所示 管理员希望在NGFW A和NGFW B之间建立IKE方式的IPSec隧道 使网络A和网络B的用户可以通过IPSec隧道互相访问 图1 IPSec 不通组网图 配
  • mysql大量数据迁移

    http blog csdn net blakefez article details 51076588 最近有个需求 要把机器a上的一个数据库迁移到机器b上 这个数据库的数据有100多个G 所以 果断抛弃用mysqldump的方法来迁移
  • SWD调试接口接上下拉电阻

    在使用NXP的Kinetis系列的KV1X的MCU时 此款芯片只有SWD调试接口 在使用kei调试和下载过程中时不时会找不到SWD接口或者芯片被锁住 检查电源稳定纹波很小 NMI已上拉10k电阻 可以在jlink Command中找到内核并
  • MYSQL--基础--04--索引原理

    MYSQL 基础 04 索引原理 1 索引原理 1 1 索引的目的 提高查询效率 与我们查阅图书所用的目录是一个道理 先定位到章 然后定位到该章下的一个小节 然后找到页数 1 2 索引的本质 通过不断地缩小想要获取数据的范围来筛选出最终想要
  • 3.全志H3-编译官方BSP

    上面是我的微信和QQ群 欢迎新朋友的加入 原文链接 http wiki friendlyarm com wiki index php Building U boot and Linux for H5 H3 H2 2B zh 使用全志原厂BS
  • [编程入门]猴子吃桃的问题(JAVA解法)

    题目描述 猴子吃桃问题 猴子第一天摘下若干个桃子 当即吃了一半 还不过瘾 又多吃了一个 第二天早上又将剩下的桃子吃掉一半 又多吃一个 以后每天早上都吃了前一天剩下的一半零一个 到第N天早上想再吃时 见只剩下一个桃子了 求第一天共摘多少桃子
  • 机器学习_深度学习毕设题目汇总——问答

    下面是该类的一些题目 题目 基于关系建模的视觉问答研究 基于注意力机制与高层语义的视觉问答研究 基于深度学习的交互式问答技术研究 基于深度学习的结构化数据问答方法研究 智能视觉问答中关键问题的理论与方法研究 社区问答平台上多因素融合的答案选
  • 上传自己封装的python包到PyPI

    请参考 https www jianshu com p 81fe5a5cd27a
  • 【数据结构】顺序表实现增删查改

    目录 1 顺序表的创建 1 1 静态版 1 2动态版 2 顺序表初始化 2 1传值初始化 2 2传址初始化 3 实现尾插 4 打印函数 5 头插 6 检查空间容量 7 尾删 8 释放空间函数 9 头删 10 在某处插入 11 某地方删除 1
  • CppUTest——【由JUnit移植过来的】C++单元测试框架——的下载安装

    C 单元测试框架CppUTest的下载与安装 简介 下载地址 单元测试框架下载 单元测试被测工程下载 安装 安装Cygwin 下载地址 安装步骤 手动安装CMake 编译单元测试框架CppUTest 导入到Virtual Studio 准备
  • c++在线编译器

    https wandbox org
  • PID控制的深入探讨(位置式PID、增量式PID、PID的积分饱和)

    本文主要探讨PID算法在使用时的一些实际问题 处理技巧和方法 学习本节内容需要先对PID控制算法有基本的了解 1 PID控制的基本原理 PID是一个二阶线性控制器 它具有不需要建立数学模型 控制效果好 良好的鲁棒性等等优点 它的原理如下图
  • go grpc实战

    go rpc实战 什么是rpc以及rpc的原理就不加以阐述了 wiki rpc对其进行了说明 本文 以登录过程为例 使用go作为开发语言 使用grpc库实现了登录接口 具体过程及代码如下所示 环境准备 在app的同级目录创建appGoPat