一、概念

1、gRPC默认使用protocol buffers,这是google开源的一套成熟的结构数据序列化机制(当然也可以使用其他数据格式如JSON),可以用proto files创建gRPC服务,用protocol buffers消息类型来定义方法参数和返回类型。

二、安装

1、yum install autoconf automake libtool  (centos 系统)

2、protocal buffer安装

从 https://github.com/google/protobuf/releases下载安装包,解压,然后操作以下命令:

./autogen.sh
./configure
make
make install

最后设置环境变量即可:export LD_LIBRARY_PATH=/usr/local/lib

3、安装 golang protobuf

go get -u github.com/golang/protobuf/proto // golang protobuf 库
go get -u github.com/golang/protobuf/protoc-gen-go //protoc --go_out 工具

4、安装 gRPC-go

go get google.golang.org/grpc

无法下载的话去 https://github.com/grpc/grpc-go 下载

三、使用

1、编写 proto 文件,helloworld.proto

syntax = "proto3";

option objc_class_prefix = "HLW";

package helloworld;

// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
} // The request message containing the user's name.
message HelloRequest {
string name = 1;
} // The response message containing the greetings
message HelloReply {
string message = 1;
}
  • syntax="proto3":指定protobuf的版本
  • package helloworld:声明一个报名,一般与文件目录名相同
  • import "xxx/xx.proto":导入其他的包,这样你就可以使用其他的包的数据结构
  • required、optional、repeated:表示该字段是否必须填充;required表示必须指定且只能指定一个;当optional表示可选,可指定也可不指定,但不可超过一个不指定值的时候会采用空值,如string类型的字段会用字符串表示;repeated表示可以重复,类似与编程语言中的list
  • message Author:在一个message体内定义一个message结构体
  • enum:是枚举类型结构体
  • 数字:字段的标识符,不可重复
  • 数据类型: int32、int64、uint32、uint64、sint32、sint64、double、float、 string、bool、bytes、enum、message等等

2、使用protoc命令生成相关文件:

protoc --go_out=plugins=grpc:. helloworld.proto
ls
helloworld.pb.go helloworld.proto

这里用了plugins选项,提供对grpc的支持,否则不会生成Service的接口,方便编写服务器和客户端程序

helloworld.pb.go 文件如下:

 // Code generated by protoc-gen-go. DO NOT EDIT.
// source: helloworld.proto package helloworld import (
context "context"
fmt "fmt"
proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc"
math "math"
) // Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf // This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // The request message containing the user's name.
type HelloRequest struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} func (m *HelloRequest) Reset() { *m = HelloRequest{} }
func (m *HelloRequest) String() string { return proto.CompactTextString(m) }
func (*HelloRequest) ProtoMessage() {}
func (*HelloRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_17b8c58d586b62f2, []int{0}
} func (m *HelloRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_HelloRequest.Unmarshal(m, b)
}
func (m *HelloRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_HelloRequest.Marshal(b, m, deterministic)
}
func (m *HelloRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_HelloRequest.Merge(m, src)
}
func (m *HelloRequest) XXX_Size() int {
return xxx_messageInfo_HelloRequest.Size(m)
}
func (m *HelloRequest) XXX_DiscardUnknown() {
xxx_messageInfo_HelloRequest.DiscardUnknown(m)
} var xxx_messageInfo_HelloRequest proto.InternalMessageInfo func (m *HelloRequest) GetName() string {
if m != nil {
return m.Name
}
return ""
} // The response message containing the greetings
type HelloReply struct {
Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} func (m *HelloReply) Reset() { *m = HelloReply{} }
func (m *HelloReply) String() string { return proto.CompactTextString(m) }
func (*HelloReply) ProtoMessage() {}
func (*HelloReply) Descriptor() ([]byte, []int) {
return fileDescriptor_17b8c58d586b62f2, []int{1}
} func (m *HelloReply) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_HelloReply.Unmarshal(m, b)
}
func (m *HelloReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_HelloReply.Marshal(b, m, deterministic)
}
func (m *HelloReply) XXX_Merge(src proto.Message) {
xxx_messageInfo_HelloReply.Merge(m, src)
}
func (m *HelloReply) XXX_Size() int {
return xxx_messageInfo_HelloReply.Size(m)
}
func (m *HelloReply) XXX_DiscardUnknown() {
xxx_messageInfo_HelloReply.DiscardUnknown(m)
} var xxx_messageInfo_HelloReply proto.InternalMessageInfo func (m *HelloReply) GetMessage() string {
if m != nil {
return m.Message
}
return ""
} func init() {
proto.RegisterType((*HelloRequest)(nil), "helloworld.HelloRequest")
proto.RegisterType((*HelloReply)(nil), "helloworld.HelloReply")
} func init() { proto.RegisterFile("helloworld.proto", fileDescriptor_17b8c58d586b62f2) } var fileDescriptor_17b8c58d586b62f2 = []byte{
// 149 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xc8, 0x48, 0xcd, 0xc9,
0xc9, 0x2f, 0xcf, 0x2f, 0xca, 0x49, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x42, 0x88,
0x28, 0x29, 0x71, 0xf1, 0x78, 0x80, 0x78, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25, 0x42, 0x42,
0x5c, 0x2c, 0x79, 0x89, 0xb9, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x60, 0xb6, 0x92,
0x1a, 0x17, 0x17, 0x54, 0x4d, 0x41, 0x4e, 0xa5, 0x90, 0x04, 0x17, 0x7b, 0x6e, 0x6a, 0x71, 0x71,
0x62, 0x3a, 0x4c, 0x11, 0x8c, 0x6b, 0xe4, 0xc9, 0xc5, 0xee, 0x5e, 0x94, 0x9a, 0x5a, 0x92, 0x5a,
0x24, 0x64, 0xc7, 0xc5, 0x11, 0x9c, 0x58, 0x09, 0xd6, 0x25, 0x24, 0xa1, 0x87, 0xe4, 0x02, 0x64,
0xcb, 0xa4, 0xc4, 0xb0, 0xc8, 0x14, 0xe4, 0x54, 0x2a, 0x31, 0x38, 0xb1, 0x2d, 0x62, 0x62, 0xf6,
0xf0, 0x09, 0x4f, 0x62, 0x03, 0xbb, 0xd8, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xbe, 0xde, 0x1d,
0x2e, 0xc5, 0x00, 0x00, 0x00,
} // Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn // This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4 // GreeterClient is the client API for Greeter service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type GreeterClient interface {
// Sends a greeting
SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
} type greeterClient struct {
cc *grpc.ClientConn
} func NewGreeterClient(cc *grpc.ClientConn) GreeterClient {
return &greeterClient{cc}
} func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) {
out := new(HelloReply)
err := c.cc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
} // GreeterServer is the server API for Greeter service.
type GreeterServer interface {
// Sends a greeting
SayHello(context.Context, *HelloRequest) (*HelloReply, error)
} func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) {
s.RegisterService(&_Greeter_serviceDesc, srv)
} func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(HelloRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GreeterServer).SayHello(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/helloworld.Greeter/SayHello",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest))
}
return interceptor(ctx, in, info, handler)
} var _Greeter_serviceDesc = grpc.ServiceDesc{
ServiceName: "helloworld.Greeter",
HandlerType: (*GreeterServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "SayHello",
Handler: _Greeter_SayHello_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "helloworld.proto",
}

3、服务器程序

package main

import (
"log"
"net" pb "test_grpc/helloworld"
"google.golang.org/grpc"
"golang.org/x/net/context"
) const (
PORT = ":50001"
) type server struct {} func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
log.Println("request: ", in.Name)
return &pb.HelloReply{Message: "Hello " + in.Name}, nil
} func main() {
lis, err := net.Listen("tcp", PORT) if err != nil {
log.Fatalf("failed to listen: %v", err)
} s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
log.Println("rpc服务已经开启")
s.Serve(lis)
}

4、客户端程序

package main

import (
"log"
"os" pb "test_grpc/helloworld"
"golang.org/x/net/context"
"google.golang.org/grpc"
) const (
address = "localhost:50001"
) func main() {
conn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil {
log.Fatalf("did not connect: %v", err)
} defer conn.Close() c := pb.NewGreeterClient(conn) name := "lin"
if len(os.Args) > 1 {
name = os.Args[1]
} r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name}) if err != nil {
log.Fatalf("could not greet: %v", err)
} log.Println(r.Message)
}

Golang gRPC 使用的更多相关文章

  1. Golang gRPC调试工具

    目录 Golang gRPC调试工具 1. 命令行工具 grpcurl 1.1 安装 1.2 验证 1.3 注册反射 1.4 使用示例 2. web调试工具grpcui 2.1 安装 2.2 验证 2 ...

  2. Golang gRPC 示例

    1.安装gRPC runtime go get google.golang.org/grpc 为了自动生成Golang的gRPC代码,需要安装protocal buffers compiler以及对应 ...

  3. Golang gRPC 和 gRPC-gateway 结合使用

    一.安装 go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway go get -u github.com/g ...

  4. [golang grpc] 框架介绍

    官方网站 http://www.grpc.io/ http://www.grpc.io/docs/quickstart/go.html grpc安装 • go安装 目前grpc需要go 1.5以上版本 ...

  5. Golang gRPC微服务02: helloworld

    安装protobuf 在windows下,直接下载release版本https://github.com/protocolbuffers/protobuf/releases/tag/v3.9.0然后把 ...

  6. Golang gRPC微服务01: 介绍

    gRPC 是什么 gRPC是goole开源的一个RPC框架和库,支持多语言之间的通信.底层通信采用的是 HTTP2 协议.gRPC在设计上使用了 ProtoBuf 这种接口描述语言.这种IDL语言可以 ...

  7. golang gRPC初探

    gRPC使用protocol buffers作为Interface Definition Language (IDL). gRPC的底层信息交互格式也使用的是protocol buffers. 默认情 ...

  8. Golang gRPC学习(04): Deadlines超时限制

    为什么要使用Deadlines 当我们使用gRPC时,gRPC库关系的是连接,序列化,反序列化和超时执行.Deadlines 允许gRPC客户端设置自己等待多长时间来完成rpc操作,直到出现这个错误 ...

  9. golang grpc demo

    1.grpm 安装: git clone https://github.com/grpc/grpc-go.git $GOPATH/src/google.golang.org/grpc 2.proto, ...

随机推荐

  1. hdu 1231 最大连续子序列 ,1003 Max Sum;

    题目(1231) #include<stdio.h> #include<iostream> using namespace std; int main() { int K,nu ...

  2. java递归和反向递归

    1. 递归查询树tree结构有两种做法: 第一种,递归查询数据库结构, 第二种,一次性将数据库表中的所有数据查出来,然后再递归查出来的list集合, 第一种做法适合数据量较少的tree结构,因为要一直 ...

  3. Python学习-22.Python中的函数——type

    type函数可以检测任何值或变量的类型. 例子: def printType(var): print(type(var)) class TestClass: pass printType(1) pri ...

  4. 一个初学者的指南,使用D3做数据绑定

    一个初学者的指南,使用D3做数据绑定 D3.js 是个强大的数据可视化库,可以做出惊艳的图表.比如:气泡图,线图和条形图--只需要很少行的代码 随着初学者对JavaScript的理解,可以将数组或者对 ...

  5. nodejs vinyl-fs 处理文件时输入问题

    使用 nodejs vinyl-fs 复制文件时输出路径不对,还是会有原来的相对路径,原因是用了反斜杠“\”,正斜杠“/”没问题 测试过程 node版本: v9.3.0 系统:win10 步骤: 得到 ...

  6. (C#)计算1-2+3-4+.....+m

    方法一: public static int Sum(int m) { int sum = 0; bool bol = true; for (int i=1;i<=m;i++) { if (bo ...

  7. 虚拟安装centos后无法上网、DNS无法解析问题解决

    1.保证拟机ip和VMnet8的ip在同一网段内 2.虚拟机网关和VMnet8相同

  8. 任务查询系统(cqoi2015,bzoj3932)(主席树)

    最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组\((S_i,E_i,P_i)\)描述,\((S_i,E_i,P_i)\)表示任务从第 ...

  9. python 匿名函数 lambda 的使用

    在python中,lambda允许用户快速定义单行函数,当然用户也可以按照典型的函数定义完成函数.lambda的目的就是简化用户定义使用函数的过程. In [6]: s = lambda x: x+1 ...

  10. thinkphp5的mkdir() Permission denied问题

    最近一直在用tp5写项目,在此遇到的问题也比较多.今天来谈谈“mkdir() Permission denied”错误. 你如果不仅仅写代码,还得部署到线上,那么这个tp5的这个错误,你有很大概率会遇 ...