Go gRPC Hello World
概述
开始 gRPC 了,这篇文章学习使用 gRPC,输出一个 Hello World。
用 Go 实现 gRPC 的服务端。
用 Go 实现 gRPC 的客户端。
gRPC 支持 4 类服务方法,咱们这次实现 单项 RPC 和 服务端流式 RPC。
四类服务方法
单项 RPC
服务端发送一个请求给服务端,从服务端获取一个应答,就像一次普通的函数调用。
rpc SayHello(HelloRequest) returns (HelloResponse){}
服务端流式 RPC
客户端发送一个请求给服务端,可获取一个数据流用来读取一系列消息。客户端从返回的数据流里一直读取直到没有更多消息为止。
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){}
客户端流式 RPC
客户端用提供的一个数据流写入并发送一系列消息给服务端。一旦客户端完成消息写入,就等待服务端读取这些消息并返回应答。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {}
双向流式 RPC
两边都可以分别通过一个读写数据流来发送一系列消息。这两个数据流操作是相互独立的,所以客户端和服务端能按其希望的任意顺序读写,例如:服务端可以在写应答前等待所有的客户端消息,或者它可以先读一个消息再写一个消息,或者是读写相结合的其他方式。每个数据流里消息的顺序会被保持。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){}
安装
安装 protobuf 编译器
brew install protobuf
验证:
protoc --version
//输出:libprotoc 3.7.1
安装 Go protobuf 插件
go get -u github.com/golang/protobuf/proto
go get -u github.com/golang/protobuf/protoc-gen-go
安装 grpc-go
go get -u google.golang.org/grpc
写个 Hello World 服务
编写服务端 .proto 文件
生成服务端 .pb.go 文件并同步给客户端
编写服务端提供接口的代码
编写客户端调用接口的代码
目录结构
├─ hello -- 代码根目录
│ ├─ go_client
│ ├── main.go
│ ├── proto
│ ├── hello
│ ├── hello.pb.go
│ ├─ go_server
│ ├── main.go
│ ├── controller
│ ├── hello_controller
│ ├── hello_server.go
│ ├── proto
│ ├── hello
│ ├── hello.pb.go
│ ├── hello.proto
这样创建目录是为了 go_client 和 go_server 后期可以拆成两个项目。
编写服务端 hello.proto 文件
syntax = "proto3"; // 指定 proto 版本
package hello; // 指定包名
// 定义 Hello 服务
service Hello {
// 定义 SayHello 方法
rpc SayHello(HelloRequest) returns (HelloResponse) {}
// 定义 LotsOfReplies 方法
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){}
}
// HelloRequest 请求结构
message HelloRequest {
string name = 1;
}
// HelloResponse 响应结构
message HelloResponse {
string message = 1;
}
了解更多 Protobuf 语法,请查看:
https://developers.google.com/protocol-buffers/
生成服务端 .pb.go
protoc -I . --go_out=plugins=grpc:. ./hello.proto
同时将生成的 hello.pb.go 复制到客户端一份。
查看更多命令参数,执行 protoc,查看 OPTION 。
编写服务端提供接口的代码
// hello_server.go
package hello_controller
import (
"fmt"
"golang.org/x/net/context"
"hello/go_server/proto/hello"
)
type HelloController struct{}
func (h *HelloController) SayHello(ctx context.Context, in *hello.HelloRequest) (*hello.HelloResponse, error) {
return &hello.HelloResponse{Message : fmt.Sprintf("%s", in.Name)}, nil
}
func (h *HelloController) LotsOfReplies(in *hello.HelloRequest, stream hello.Hello_LotsOfRepliesServer) error {
for i := 0; i < 10; i++ {
stream.Send(&hello.HelloResponse{Message : fmt.Sprintf("%s %s %d", in.Name, "Reply", i)})
}
return nil
} // main.go
package main
import (
"log"
"net"
"hello/go_server/proto/hello"
"hello/go_server/controller/hello_controller"
"google.golang.org/grpc"
)
const (
Address = "0.0.0.0:9090"
)
func main() {
listen, err := net.Listen("tcp", Address)
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
s := grpc.NewServer()
// 服务注册
hello.RegisterHelloServer(s, &hello_controller.HelloController{})
log.Println("Listen on " + Address)
if err := s.Serve(listen); err != nil {
log.Fatalf("Failed to serve: %v", err)
}
}
运行:
go run main.go
2019/07/28 17:51:20 Listen on 0.0.0.0:9090
编写客户端请求接口的代码
package main
import (
"hello/go_client/proto/hello"
"io"
"log"
"golang.org/x/net/context"
"google.golang.org/grpc"
)
const (
// gRPC 服务地址
Address = "0.0.0.0:9090"
)
func main() {
conn, err := grpc.Dial(Address, grpc.WithInsecure())
if err != nil {
log.Fatalln(err)
}
defer conn.Close()
// 初始化客户端
c := hello.NewHelloClient(conn)
// 调用 SayHello 方法
res, err := c.SayHello(context.Background(), &hello.HelloRequest{Name: "Hello World"})
if err != nil {
log.Fatalln(err)
}
log.Println(res.Message)
// 调用 LotsOfReplies 方法
stream, err := c.LotsOfReplies(context.Background(),&hello.HelloRequest{Name: "Hello World"})
if err != nil {
log.Fatalln(err)
}
for {
res, err := stream.Recv()
if err == io.EOF {
break
}
if err != nil {
log.Printf("stream.Recv: %v", err)
}
log.Printf("%s", res.Message)
}
}
运行:
go run main.go
2019/07/28 17:58:13 Hello World
2019/07/28 17:58:13 Hello World Reply 0
2019/07/28 17:58:13 Hello World Reply 1
2019/07/28 17:58:13 Hello World Reply 2
2019/07/28 17:58:13 Hello World Reply 3
2019/07/28 17:58:13 Hello World Reply 4
2019/07/28 17:58:13 Hello World Reply 5
2019/07/28 17:58:13 Hello World Reply 6
2019/07/28 17:58:13 Hello World Reply 7
2019/07/28 17:58:13 Hello World Reply 8
Go gRPC Hello World的更多相关文章
- gRPC源码分析1-SSL/TLS
引子 前几天看到微信后台团队分享了TLS相关文章,正好gRPC里TLS数据加密是很重要的一块,于是整理出了这篇文章. 在gRPC里,如果仅仅是用来做后端微服务,可以考虑不加密.本文太长,先给个大纲. ...
- gRPC源码分析2-Server的建立
gRPC中,Server.Client共享的Class不是很多,所以我们可以单独的分别讲解Server和Client的源码. 通过第一篇,我们知道对于gRPC来说,建立Server是非常简单的,还记得 ...
- gRPC源码分析0-导读
gRPC是Google开源的新一代RPC框架,官网是http://www.grpc.io.正式发布于2016年8月,技术栈非常的新,基于HTTP/2,netty4.1,proto3.虽然目前在工程化方 ...
- 谷歌发布的首款基于HTTP/2和protobuf的RPC框架:GRPC
Google 刚刚开源了grpc, 一个基于HTTP2 和 Protobuf 的高性能.开源.通用的RPC框架.Protobuf 本身虽然提供了RPC 的定义语法,但是一直以来,Google 只开 ...
- gRPC .NET Core跨平台学习
前些天发布gRPC C# 学习,在.NET Framework 中使用gRPC ,今天来学习 .NET Core gRPC. gRPC 的.NET Core 包在NuGet 上发布了,结合.NET C ...
- gRPC C#学习
前些天gRPC 发布1.0 版本,代表着gRPC 已经正式进入稳定阶段. 今天我们就来学习gRPC C# .而且目前也已经支持.NET Core 可以实现完美跨平台. 传统的.NET 可以通过Mono ...
- .net core 用grpc实现微服务
GRPC 是Google发布的一个开源.高性能.通用RPC(Remote Procedure Call)框架.提供跨语言.跨平台支持.以下以.NET Core 使用控制台.docker中演示如何使用G ...
- rpc框架之gRPC 学习 - hello world
grpc是google在github于2015年开源的一款RPC框架,虽然protobuf很早google就开源了,但是google一直没推出正式的开源框架,导致github上基于protobuf的r ...
- Android开发笔记之《远程控制(MQTT|mosquitto) && (ProtocalBuffer | GRPC)》
Android推送方案分析(MQTT/XMPP/GCM): http://www.open-open.com/lib/view/open1410848945601.htmlMQTT官网: http:/ ...
- gRPC+etcd的优势分析
相比webService等可跨平台,跨语言的服务相比,gRPC更增加了以下优势 1.可以采用二进制传输,速度更快 (使用TCP传输层,而不是Http2应用层) 2.集群服务,统一注册,可靠性高( 好的 ...
随机推荐
- 【计算机网络】如何让Ajax通信过程携带Cookie呢?
Ajax 1. 介绍一下ajax并代码实现 1.1 基本概念 JavaScript 和XML(Asynchronous JavaScript And XML).简单点说,就是使用 XMLHttpReq ...
- java Integer中隐藏的细节魔鬼!来自面试官的三轮暴击!
1 第一波暴击!!! 程序员比较实在,一般会说: 那就先上代码 package com.example.demo; public class TestInteger { public static v ...
- Spring5源码解析2-register方法注册配置类
接上回已经讲完了this()方法,现在来看register(annotatedClasses);方法. // new AnnotationConfigApplicationContext(AppCon ...
- VS2019安装好后,经常打不开软件没反应解决方法
原文地址:https://blog.csdn.net/FL1623863129/article/details/89013137 VS2019于昨日正式发布,博主立马下载一个专业版尝尝鲜,但是发现项目 ...
- python读取Excel的值
上代码: import pandas as pd if __name__ == '__main__': #默认的读取第一个sheet df = pd.read_excel("E:\\MyPr ...
- c#图片相关常用的方法及处理
总结一下图片相关,常用的几个操作 一 创建Image对象 1. 手头上有一些图片文件,希望转换成 c# 中 Image对象,然后加以使用. public static System.Drawing ...
- Http协议(自己的一些小小的总结,方便日后学习揣摩)
从2019年6月中旬开始学习JAVA已经差不多6个月了,也算是差不多半只脚踏进了JAVA的大门,没有老师带,遇到问题就要自己查百度,搜博客,去给各个大佬私信留言,也不知道看不看的见. 看了很多大佬的视 ...
- JDK1.8新特性——使用新的方式遍历集合
JDK1.8新特性——使用新的方式遍历集合 摘要:本文主要学习了在JDK1.8中新增的遍历集合的方式. 遍历List 方法: default void forEach(Consumer<? su ...
- collection(list,set,map)集合详解
一:java集合的体系结构如下: Java集合大致分为Set.List.Queue.Map四个体系 .Collection: List和Set,Queue继承自Collection接口. |--Lis ...
- 【hexo+github搭建myblog】bash: npm: command not found 问题,疑似解决!关键词:NPM全局安装路径
情况:打算用hexo+github搭建个人博客 1. hexo搭建,参考博文如下,非常感谢: Hexo+Github博客搭建完全教程 hexo从零开始到搭建完整 问题: 在最基本的安装步骤 (参考链接 ...