Go GRPC 入门(二)
前言
最近较忙,其实准备一篇搞定的
中途有事,只能隔了一天再写
正文
pb.go
需要注意的是,在本个 demo 中,客户端与服务端都是 Golang
,所以在客户端与服务端都公用一个 pb.go
模板文件(如果是不同的语言生成的pb是对应语言),可以将 pb.go
文件放置在云上由双方引用,也可以生成两个副本放在两端项目中,本次就使用 COPY
两份的方式
由于 Golang
一个文件夹只有一个 package
,而生成的 pb.go
文件 package
为创建 proto
的名字(示例为 spider
), 所以我们在项目内单独建立文件夹 spider
将文件放入其中即可正常使用
编写 server 端
编写 main.go
文件
package main
import (
"context"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
"io/ioutil"
"net"
"net/http"
"server/spider"
)
type server struct{}
const (
// Address 监听地址
Address string = "localhost:8080"
// Method 通信方法
Method string = "tcp"
)
// 接收client端的请求,函数名需保持一致
// ctx参数必传
// 参数二为自定义的参数,需从pb文件导入,因此pb文件必须可导入,文件放哪里随意
// 返回值同参数二,为pb文件的返回结构体指针
func (s *server) GetAddressResponse(ctx context.Context, a *spider.SendAddress) (*spider.GetResponse, error) {
// 逻辑写在这里
switch a.Method {
case "get", "Get", "GET":
// 演示微服务用,故只写get示例
status, body, err := get(a.Address)
if err != nil {
return nil, err
}
res := spider.GetResponse{
HttpCode: int32(status),
Response: body,
}
return &res, nil
}
return nil, nil
}
func get(address string) (s int, r string, err error) {
// get请求
resp, err := http.Get(address)
if err != nil {
return
}
defer resp.Body.Close()
s = resp.StatusCode
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return
}
r = string(body)
return
}
func main() {
// 监听本地端口
listener, err := net.Listen(Method, Address)
if err != nil {
return
}
s := grpc.NewServer() // 创建GRPC
spider.RegisterGoSpiderServer(s, &server{}) // 在GRPC服务端注册服务
reflection.Register(s) // 在GRPC服务器注册服务器反射服务
// Serve方法接收监听的端口,每到一个连接创建一个ServerTransport和server的grroutine
// 这个goroutine读取GRPC请求,调用已注册的处理程序进行响应
err = s.Serve(listener)
if err != nil {
return
}
}
编写 client 端
package main
import (
"client/spider"
"context"
"google.golang.org/grpc"
)
import "fmt"
const (
// Address server端地址
Address string = "localhost:8080"
)
func main() {
// 连接服务器
conn, err := grpc.Dial(Address, grpc.WithInsecure())
if err != nil {
fmt.Println(err)
return
}
defer conn.Close()
// 连接GRPC
c := spider.NewGoSpiderClient(conn)
// 创建要发送的结构体
req := spider.SendAddress{
Address: "http://www.baidu.com",
Method: "get",
}
// 调用server的注册方法
r, err := c.GetAddressResponse(context.Background(), &req)
if err != nil {
fmt.Println(err)
return
}
// 打印返回值
fmt.Println(r)
}
运行
需要先启动 server 端监听端口,再启动 client 端向端口发送请求
我们运行后可看到结果已经正常返回并打印
Go GRPC 入门(二)的更多相关文章
- grpc入门(三)
grpc入门(三) 一.介绍 本文是关于grpc的第三篇博文,是对前两篇博文的具体代码实现,秉着个人一贯的风格,没有太多抒情和总结,直接就上代码. 文章代码参考:https://github.com/ ...
- 微服务架构攀登之路(三)之gRPC入门
一.gRPC入门 1. gRPC 简介 gRPC 由 google 开发,是一款语言中立.平台中立.开源的远程过程调用系统 gRPC 客户端和服务端可以在多种环境中运行和交互,例如用 java 写一个 ...
- 【原创】NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示
前言 NIO框架的流行,使得开发大并发.高性能的互联网服务端成为可能.这其中最流行的无非就是MINA和Netty了,MINA目前的主要版本是MINA2.而Netty的主要版本是Netty3和Netty ...
- Swift语法基础入门二(数组, 字典, 字符串)
Swift语法基础入门二(数组, 字典, 字符串) 数组(有序数据的集) *格式 : [] / Int / Array() let 不可变数组 var 可变数组 注意: 不需要改变集合的时候创建不可变 ...
- Thinkphp入门 二 —空操作、空模块、模块分组、前置操作、后置操作、跨模块调用(46)
原文:Thinkphp入门 二 -空操作.空模块.模块分组.前置操作.后置操作.跨模块调用(46) [空操作处理] 看下列图: 实际情况:我们的User控制器没有hello()这个方法 一个对象去访问 ...
- DevExpress XtraReports 入门二 创建 data-aware(数据感知) 报表
原文:DevExpress XtraReports 入门二 创建 data-aware(数据感知) 报表 本文只是为了帮助初次接触或是需要DevExpress XtraReports报表的人群使用的, ...
- css入门二-常用样式
css入门二-常用样式总结 基本标签样式 背景色background-color 高度height; 宽度width; 边框对齐以及详细设定举例 width/*宽度*/: 80%; height/*高 ...
- 微服务(入门二):netcore通过consul注册服务
基础准备 1.创建asp.net core Web 应用程序选择Api 2.appsettings.json 配置consul服务器地址,以及本机ip和端口号信息 { "Logging&qu ...
- IM开发者的零基础通信技术入门(二):通信交换技术的百年发展史(下)
1.系列文章引言 1.1 适合谁来阅读? 本系列文章尽量使用最浅显易懂的文字.图片来组织内容,力求通信技术零基础的人群也能看懂.但个人建议,至少稍微了解过网络通信方面的知识后再看,会更有收获.如果您大 ...
随机推荐
- CSP-S 2020 题解
赛后我重拳出击,赛场上我却爆零.哎. 题解本人口胡.有错请各位大佬们指出. A. 儒略日 这题是大型模拟题. 介绍两种写法:一种代码量致死(赛 场 自 闭),一种是非常好写的. 写法 1 我在赛场的思 ...
- CF1320 Div1 D.Reachable Strings 题解
题目大意 给定一个长为\(n\)的01串\(S\),每次你可以对一个串的三个连续位置做:\(011 \rightarrow 110\),\(110 \rightarrow 011\)的操作. 有\(q ...
- pyppeteer 登录一般网站 并利用 http方法获取登录页面的验证码
主函数 新建浏览器,进行登录,由于验证码的识别准确率不是百分之百,需要多次尝试. async def main(self, username, pwd, url): # 定义main协程函数, log ...
- Oracle 迁移数据库到 mysql
一. oracle导出.sql文件(Navicat Premiu 11.0.8 无法实现oracle到mysql的数据传输亲测有效) exp username/pass@数据局地址ip:1521/ ...
- html文本域textarea高度自增、自动换行
文本域自动换行.高度自增,采用以下方式: html: <textarea rows="1" class="answerTextArea" maxlengt ...
- 云原生时代,Java的危与机(周志明)
说明 本篇文章是转载自周志明老师的文章,链接地址:https://www.infoq.cn/article/RQfWw2R2ZpYQiOlc1WBE 今天,25 岁的 Java 仍然是最具有统治力的编 ...
- css 10-CSS3选择器详解
10-CSS3选择器详解 #CSS3介绍 CSS3在CSS2基础上,增强或新增了许多特性, 弥补了CSS2的众多不足之处,使得Web开发变得更为高效和便捷. #CSS3的现状 浏览器支持程度不够好,有 ...
- 利用Java Flight Recorder(JFR)诊断timing及内存问题
Java Flight Recorder(JFR), 以下简称JFR,请注意这个只有Oracle JDK 1.7(7u40)或以上版本才有, OpenJDK木有这东西. 启用: Java命令行启动参数 ...
- 6 个例子教你重构 Python 代码
1. 合并嵌套的 if 条件 太多的嵌套会使代码难以理解,这在 Python 中尤为如此,因为 Python 没有括号来帮助区隔不同的嵌套级别. 阅读深度嵌套的代码容易让人烦躁,因为你必须理清哪些条件 ...
- ArrayList哪种循环效率更好你真的清楚吗
ArrayList简介 声明:以下内容都是基于jdk1.8的 ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了 ...