概述

开始 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的更多相关文章

  1. gRPC源码分析1-SSL/TLS

    引子 前几天看到微信后台团队分享了TLS相关文章,正好gRPC里TLS数据加密是很重要的一块,于是整理出了这篇文章. 在gRPC里,如果仅仅是用来做后端微服务,可以考虑不加密.本文太长,先给个大纲. ...

  2. gRPC源码分析2-Server的建立

    gRPC中,Server.Client共享的Class不是很多,所以我们可以单独的分别讲解Server和Client的源码. 通过第一篇,我们知道对于gRPC来说,建立Server是非常简单的,还记得 ...

  3. gRPC源码分析0-导读

    gRPC是Google开源的新一代RPC框架,官网是http://www.grpc.io.正式发布于2016年8月,技术栈非常的新,基于HTTP/2,netty4.1,proto3.虽然目前在工程化方 ...

  4. 谷歌发布的首款基于HTTP/2和protobuf的RPC框架:GRPC

    Google 刚刚开源了grpc,  一个基于HTTP2 和 Protobuf 的高性能.开源.通用的RPC框架.Protobuf 本身虽然提供了RPC  的定义语法,但是一直以来,Google 只开 ...

  5. gRPC .NET Core跨平台学习

    前些天发布gRPC C# 学习,在.NET Framework 中使用gRPC ,今天来学习 .NET Core gRPC. gRPC 的.NET Core 包在NuGet 上发布了,结合.NET C ...

  6. gRPC C#学习

    前些天gRPC 发布1.0 版本,代表着gRPC 已经正式进入稳定阶段. 今天我们就来学习gRPC C# .而且目前也已经支持.NET Core 可以实现完美跨平台. 传统的.NET 可以通过Mono ...

  7. .net core 用grpc实现微服务

    GRPC 是Google发布的一个开源.高性能.通用RPC(Remote Procedure Call)框架.提供跨语言.跨平台支持.以下以.NET Core 使用控制台.docker中演示如何使用G ...

  8. rpc框架之gRPC 学习 - hello world

    grpc是google在github于2015年开源的一款RPC框架,虽然protobuf很早google就开源了,但是google一直没推出正式的开源框架,导致github上基于protobuf的r ...

  9. Android开发笔记之《远程控制(MQTT|mosquitto) && (ProtocalBuffer | GRPC)》

    Android推送方案分析(MQTT/XMPP/GCM): http://www.open-open.com/lib/view/open1410848945601.htmlMQTT官网: http:/ ...

  10. gRPC+etcd的优势分析

    相比webService等可跨平台,跨语言的服务相比,gRPC更增加了以下优势 1.可以采用二进制传输,速度更快 (使用TCP传输层,而不是Http2应用层) 2.集群服务,统一注册,可靠性高( 好的 ...

随机推荐

  1. Hbase内存磁盘大致关系

    转自: https://blog.csdn.net/wuwenxiang91322/article/details/51595771 Hbase内存磁盘关系磁盘数 diskNum磁盘容量 diskCa ...

  2. 转caffe scale layer

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/u011681952/article/det ...

  3. MySQL 联表查询

    关系型数据库,免不了表之间存在各种引用与关联.这些关联是通过主键与外键搭配来形成的.所以,取数据时,很大情况下单张表无法满足需求,额外的数据则需要将其他表加入到查询中来,这便是 JOIN 关键字完成的 ...

  4. 2018-2-13-win10-uwp-切换主题

    原文:2018-2-13-win10-uwp-切换主题 title author date CreateTime categories win10 uwp 切换主题 lindexi 2018-2-13 ...

  5. PHP+Swoole 作为网络通信框架

    PHP的异步.并行.高性能网络通信引擎,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库连接池,AsyncTask,消息队列, ...

  6. github pages与travis ci运作原理

    当说到自动部署的时候,我很反感那些一上来就balabala说怎么操作的博文文章,照着别人的做法有样学样,经常会因为与自己项目实际情况不符而出现各种问题. 比如说github和travis,首先应该搞明 ...

  7. centos 安装gitlab

    1.开始安装依赖软件:yum -y install policycoreutils openssh-server openssh-clients postfix 2.设置postfix开机自启动,po ...

  8. CSS3 3D变形 transform---rotateX(), rotateY(), rotateZ(), 透视(perspective)

    2d x y 3d x y z 左手坐标系 伸出左手,让拇指和食指成“L”形,大拇指向右,食指向上,中指指向前方.这样我们就建立了一个左手坐标系,拇指.食指和中指分别代表X.Y.Z轴的正方向.如下图 ...

  9. 转.HTML中img标签的src属性绝对路径问题解决办法,完全解决!

    HTML中img标签的src属性绝对路径问题解决办法,完全解决   需求:有时候自己的项目img的src路径需要用到本地某文件夹下的图片,而不是直接使用项目根目录下的图片. 场景:eclipse,to ...

  10. iOS多线程比较

    .iOS的三种多线程技术 .NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) .以下两点是苹果专门开发的“并发”技术,使得程序员可以不再去关心线程的具体使用问题 ØNS ...