Go-GRPC 初体验
grpc 跟常见的client-server模型相似(doubbo)
grpc 编码之前需要准备以下环境:
- 安装protobuf,grpc的client与server之间消息传递使用的protoc格式消息,比起json,xml速度快
- 安装grpc 的源码包
下面开始编写grpc示例代码:
- 首先编写proto文件,示例:helloworld
syntax = "proto3"; option objc_class_prefix = "HLW"; package helloworld; // 定义一个Greeter服务,其中API为SayHello
// 形式参数: HelloRequest
// 返回参数:HelloReply
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {} // rpc 借口的类型分为一下四种: A为接受参数,B为返回参数
// 1. rpc GetFeature(Point) returns (Feature) {} 普通调用:A-B
// 2. rpc ListFeatures(Rectangle) returns (stream Feature) {} 单向流:A - B(流)
// 3. rpc RecordRoute(stream Point) returns (RouteSummary) {} 单向流:A(流) - B
// 4. rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} 双向流:A(流) - B(流)
} // 请求参数-根据自己的需求定义
message HelloRequest {
string name = 1;
} // 返回参数-根据自己的需求定义
message HelloReply {
string message = 1;
}
2. 将helloworld.proto转化为helloworld.proto.go
命令:protoc --go_out=plugins=grpc:. helloworld.proto 结果如下:
// Code generated by protoc-gen-go.
// source: helloworld.proto
// DO NOT EDIT! /*
Package helloworld is a generated protocol buffer package. It is generated from these files:
helloworld.proto It has these top-level messages:
HelloRequest
HelloReply
*/
package myblogproto import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math" import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
) // 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.ProtoPackageIsVersion2 // please upgrade the proto package // 请求参数-根据自己的需求定义
type HelloRequest struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
} func (m *HelloRequest) Reset() { *m = HelloRequest{} }
func (m *HelloRequest) String() string { return proto.CompactTextString(m) }
func (*HelloRequest) ProtoMessage() {}
func (*HelloRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } func (m *HelloRequest) GetName() string {
if m != nil {
return m.Name
}
return ""
} // 返回参数-根据自己的需求定义
type HelloReply struct {
Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"`
} func (m *HelloReply) Reset() { *m = HelloReply{} }
func (m *HelloReply) String() string { return proto.CompactTextString(m) }
func (*HelloReply) ProtoMessage() {}
func (*HelloReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } 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")
} // 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 // Client API for Greeter service 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 := grpc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
} // 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",
} func init() { proto.RegisterFile("helloworld.proto", fileDescriptor0) } var fileDescriptor0 = []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,
}
3. 编写grpc服务端,伪代码:
package main import (
"fmt"
"golang.org/x/net/context"
"google.golang.org/grpc"
"net" pb "unicontract-validate/tests/grpcStudy/mybloggrpc/myblogproto"
) const port = ":50051" // 定义struct实现我们自定义的helloworld.proto对应的服务
type myServer struct {
} func (m *myServer) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
return &pb.HelloReply{"请求server端成功!"}, nil
} /**
1. 首先我们必须实现我们自定义rpc服务,例如:rpc SayHello()-在此我们可以实现我们自己的逻辑
2. 创建监听listener
3. 创建grpc的服务
4. 将我们的服务注册到grpc的server中
5. 启动grpc服务,将我们自定义的监听信息传递给grpc服务器
*/ func main() { // 创建server端监听端口
list, err := net.Listen("tcp", port)
if err != nil {
fmt.Println(err)
} // 创建grpc的server
server := grpc.NewServer()
// 注册我们自定义的helloworld服务
pb.RegisterGreeterServer(server, &myServer{}) // 启动grpc服务
fmt.Println("grpc 服务启动... ...")
server.Serve(list)
}
4. 编写client端代码,伪代码如下:
package main import (
"google.golang.org/grpc"
"fmt"
"context" pb "unicontract-validate/tests/grpcStudy/mybloggrpc/myblogproto"
) // 此处应与服务器端对应
const address = "127.0.0.1:50051" /**
1. 创建groc连接器
2. 创建grpc客户端,并将连接器赋值给客户端
3. 向grpc服务端发起请求
4. 获取grpc服务端返回的结果
*/
func main() { // 创建一个grpc连接器
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil{
fmt.Println(err)
}
// 当请求完毕后记得关闭连接,否则大量连接会占用资源
defer conn.Close() // 创建grpc客户端
c := pb.NewGreeterClient(conn) name := "我是客户端,正在请求服务端!!!"
// 客户端向grpc服务端发起请求
result, err := c.SayHello(context.Background(), &pb.HelloRequest{Name:name})
fmt.Println(name)
if err != nil{
fmt.Println("请求失败!!!")
return
}
// 获取服务端返回的结果
fmt.Println(result.Message)
}
服务端结果:

客户端请求之后结果:

Go-GRPC 初体验的更多相关文章
- .NET Core 微服务之grpc 初体验(干货)
Grpc介绍 GitHub: https://github.com/grpc/grpc gRPC是一个高性能.通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计 ...
- ASP.NET Core 3.0 上的gRPC服务模板初体验(多图)
早就听说ASP.NET Core 3.0中引入了gRPC的服务模板,正好趁着家里电脑刚做了新系统,然后装了VS2019的功夫来体验一把.同时记录体验的过程.如果你也想按照本文的步骤体验的话,那你得先安 ...
- RPC框架基础概念理解以及使用初体验
RPC:Remote Procedure Call(远程服务调用) RPC是做什么的 通过RPC框架机器A某个进程可以通过网络调用机器B上的进程方法,就像在本地上调用一样. RPC可以基于HTTP或者 ...
- .NET WebSockets 核心原理初体验
上个月我写了<.NET gRPC核心功能初体验>, 里面使用gRPC双向流做了一个打乒乓球的Demo, 实时双向这两个标签是不是很熟悉,对, WebSockets也可以做实时双向通信. 本 ...
- .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验
不知不觉,“.NET平台开源项目速览“系列文章已经15篇了,每一篇都非常受欢迎,可能技术水平不高,但足够入门了.虽然工作很忙,但还是会抽空把自己知道的,已经平时遇到的好的开源项目分享出来.今天就给大家 ...
- Xamarin+Prism开发详解四:简单Mac OS 虚拟机安装方法与Visual Studio for Mac 初体验
Mac OS 虚拟机安装方法 最近把自己的电脑升级了一下SSD固态硬盘,总算是有容量安装Mac 虚拟机了!经过心碎的安装探索,尝试了国内外的各种安装方法,最后在youtube上找到了一个好方法. 简单 ...
- Spring之初体验
Spring之初体验 Spring是一个轻量级的Java Web开发框架,以IoC(Inverse of Control 控制反转)和 ...
- Xamarin.iOS开发初体验
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKwAAAA+CAIAAAA5/WfHAAAJrklEQVR4nO2c/VdTRxrH+wfdU84pW0
- 【腾讯Bugly干货分享】基于 Webpack & Vue & Vue-Router 的 SPA 初体验
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57d13a57132ff21c38110186 导语 最近这几年的前端圈子,由于 ...
- 【Knockout.js 学习体验之旅】(1)ko初体验
前言 什么,你现在还在看knockout.js?这货都已经落后主流一千年了!赶紧去学Angular.React啊,再不赶紧的话,他们也要变out了哦.身旁的90后小伙伴,嘴里还塞着山东的狗不理大蒜包, ...
随机推荐
- mysql5.6 绿色免安装版 安装详解
一.安装版本简介 MySQL是一个小巧玲珑但功能强大的数据库,目前十分流行.但是官网给出的安装包有两种格式,一个是msi格式,一个是zip格式的.很多人下了zip格式的解压发现没有setup.exe, ...
- 1077. Kuchiguse (20)
The Japanese language is notorious for its sentence ending particles. Personal preference of such pa ...
- 升级 mysql5.6 配置文件my.cnf sql_mode 解析与设置问题
sql_mode是个很容易被忽视的变量,默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入.在生产环境必须将这个值设置为严格模式,所以开发.测试环境的数据库也必须要设置,这 ...
- Mybatis-no getter for property named 'col_name' in 'class com.xxx.onebean'
Mybatis中出现该异常 There is no getter for property named 'col_name' in 'class com.xxx.onebean 意思是onebean这 ...
- 赛博杯-HMI流水灯-stack
stack(ret2libc) 分析 首先checksec一下,发现没开栈保护,可能是栈溢出. [*] '/root/Desktop/bin/pwn/stack_/stack' Arch: i386- ...
- IDEA配置Struts框架
对于刚接触编程的同学,对框架只是还不是很了解,本文主要介绍在Idea上配置Struts,实现简单的页面跳转,以及页面参数传递. 在进行代码编写之前先对Idea进行一个简单了解,对于长时间接触编程的,对 ...
- oc中protocol、category和继承的区别
OC中protocol.category和继承的区别以前还是有点迷糊,面试的时候说的有点混乱,现在结合一些资料总结一下. 利用继承,多态是一个很好的保持"对扩展开放.对更改封闭"( ...
- 怎么去理解JAVA中类与对象的关系
首先要明确,在现实生活中,每一个物体都有自己的基本特征,专业一点也可以说成是属性有些甚至还有一定的行为.例如 汽车的特征:有车门.有轮胎.颜色各一等等,行为:有行驶,开车门,开车灯,等等.有这些属性和 ...
- Hibernate之ORM与Hibernate
ORM: ORM是 Object /Relation Mapping,对象/关系数据库映射. 目前比较流行的编程语言,如java ,c#等,它们都是面向对象的编程语言,而目前比较主流的数据库产品,如O ...
- 使用PostMan进行API自动化测试
最近在进行一个老项目的升级,第一步是先将node版本从4.x升级到8.x,担心升级会出现问题,所以需要将服务的接口进行验证:如果手动输入各种URL,人肉check,一个两个还行,整个服务..大几十个接 ...