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 适合谁来阅读? 本系列文章尽量使用最浅显易懂的文字.图片来组织内容,力求通信技术零基础的人群也能看懂.但个人建议,至少稍微了解过网络通信方面的知识后再看,会更有收获.如果您大 ...
随机推荐
- 【SPOJ QTREE4】Query on a tree IV(树链剖分)
Description 给出一棵边带权(\(c\))的节点数量为 \(n\) 的树,初始树上所有节点都是白色.有两种操作: C x,改变节点 \(x\) 的颜色,即白变黑,黑变白. A,询问树中最远的 ...
- Java集合源码分析(八)——WeakHashMap
简介 WeakHashMap 继承于AbstractMap,实现了Map接口. 和HashMap一样,WeakHashMap 也是一个散列表,它存储的内容也是键值对(key-value)映射,而且键和 ...
- 深入理解Java虚拟机(二)——HotSpot对象创建、内存、访问
对象的创建 虚拟机遇到一条字节码new指令时,开始对象创建过程. 首先去检查这个指令的参数是否能在常量池定位到一个类的符号引用: 检查这个符号引用代表的类是否已被加载.解析和初始化,如果没有就必须执行 ...
- dbeaver 驱动安装
一.背景: 在Windows 10 安装dbeaver数据库连接工具,点"测试连接"的时候出现报错如下: Error resolving dependencies Maven ...
- mysqldump备份数据
create database test; use test; create table test(id int,name char(8)); insert into test values(1,'p ...
- java 系统属性设置
一.语法: java -Dproperty=value 二.注意事项: value如果有空格,需用使用双引号如:java -Dfoo="some string" 三.常见使用地方: ...
- 是的,你没看错!Python可以实现自动化办公
是的,你没看错!Python可以实现自动化办公 公众号[伤心的辣条],如今越来越多的人加入到学习Python的队伍当中,尤其是对于很多职场人来说,不管你是程序员还是非程序员,Python已经为很多职场 ...
- Java源码赏析(六)Class<T> 类
目的 Class 类是每一个程序员都必须了解的,也是使用反射机制的基础. 这篇文章将Class 类的公共方法大致介绍了一遍(省略了安全.枚举.断言.注解相关代码). 代码 package java.l ...
- C#未能找到类型或命名空间名称xxxxxx的可能原因
常见原因 原因:使用的.NET版本不一样 今天又被这问题撞上了,结果神奇般的解决了 谷歌了很久都没有找到真正有用的解决方案,所以在这儿写下,让更多的人看到 最根本的原因其实就是引用的问题,引用错了,然 ...
- win7激活不支持的启动引导分区完美解决方法
前言: 激活win7显示不支持的启动引导分区怎么办?有用户使用暴风激活工具给win7 64位系统激活时,弹出Error提示框"不支持的启动引导分区". 这是因为传统的win7激活工 ...