grpc 在golang 介绍 (2)

本文深入探讨gRPC在Golang中的实现,通过route_guide.proto文件介绍服务定义,并阐述如何生成gRPC客户端和服务器端接口。接着,详细讲解了普通RPC与流式RPC的区别,包括Send()、Recv()等方法的使用场景。最后,展示了服务器启动、客户端创建及不同类型的RPC调用方法,包括简单RPC、服务器端流式RPC、客户端流式RPC和双向流式RPC的实现细节。
摘要由CSDN通过智能技术生成

上一章我们简单介绍了一下grpc 概念方面的信息,这一章我们具体学习grpc 在golang的知识。

源码地址:

https://github.com/grpc/grpc-go/tree/master/examples/route_guide

关于protocol buffers 的相关信息我们这里暂不赘述,如果有读者对这部分的知识不熟悉可以参看以下链接学习。

http://doc.oschina.net/grpc?t=60133

先上我们的route_guide.proto 文件

// Interface exported by the server.
service RouteGuide {
  // A simple RPC. 最基本的不含流式信息的rpc 接口
  //
  // Obtains the feature at a given position.
  //
  // A feature with an empty name is returned if there's no feature at the given
  // position.
  rpc GetFeature(Point) returns (Feature) {}

  // A server-to-client streaming RPC. 服务器端是流式信息的接口
  //
  // Obtains the Features available within the given Rectangle.  Results are
  // streamed rather than returned at once (e.g. in a response message with a
  // repeated field), as the rectangle may cover a large area and contain a
  // huge number of features.
  rpc ListFeatures(Rectangle) returns (stream Feature) {}

  // A client-to-server streaming RPC.  客户端是流式信息的接口
  //
  // Accepts a stream of Points on a route being traversed, returning a
  // RouteSummary when traversal is completed.
  rpc RecordRoute(stream Point) returns (RouteSummary) {}

  // A Bidirectional streaming RPC. //双端流式信息的接口
  //
  // Accepts a stream of RouteNotes sent while a route is being traversed,
  // while receiving other RouteNotes (e.g. from other users).
  rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
}

相信读者已经看出来了在我们定义的服务中,普通的rpc 与流式rpc是使用stream 进行标识。

当我们完成route_guide.proto 服务的定义后,接下来我们需要从 .proto 的服务定义中生成 gRPC 客户端和服务器端的接口。我们通过 protocol buffer 的编译器 protoc 以及一个特殊的 gRPC Go 插件来完成。

具体生成步骤我们可以参考关于protocol buffers 的链接进行学习,这部分暂时只介绍代码结构的内容。

我们会生成  route_guide.pb.go 这个文件,

文件内容包括:

  • 所有用于填充,序列化和获取我们请求和响应消息类型的 protocol buffer 代码
  • 一个为客户端调用定义在RouteGuide服务的方法的接口类型(或者 存根 )
  • 一个为服务器使用定义在RouteGuide服务的方法去实现的接口类型(或者 存根 )
package routeguide

import (...)

/*
    这部分是所有用于填充,序列化和获取我们请求和响应消息类型的 protocol buffer 代码,我们不用特别关注这些代码,所以由于篇幅的原因就不记录
如果有读者对着部分代码充满好奇可以 通过 https://github.com/grpc/grpc-go/blob/master/examples/route_guide/routeguide/route_guide.pb.go 查看
*/
// 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

// RouteGuideClient is the client API for RouteGuide service.
//
// 生成的RouteGuide 客户端接口代码
type RouteGuideClient interface {
	// A simple RPC.
	//
	GetFeature(ctx context.Context, in *Point, opts ...grpc.CallOption) (*Feature, error)
	// A server-to-client streaming RPC.
	//
	
	ListFeatures(ctx context.Context, in *Rectangle, opts ...grpc.CallOption) (RouteGuide_ListFeaturesClient, error)
	// A client-to-server streaming RPC.
	//
	RecordRoute(ctx context.Context, opts ...grpc.CallOption) (RouteGuide_RecordRouteClient, error)
	// A Bidirectional streaming RPC.
	RouteChat(ctx context.Context, opts ...grpc.CallOption) (RouteGuide_RouteChatClient, error)
}

type routeGuideClient struct {
	cc *grpc.ClientConn
}

func NewRouteGuideClient(cc *grpc.ClientConn) RouteGuideClient {
	return &routeGuideClient{cc}
}

func (c *routeGuideClient) GetFeature(ctx context.Context, in *Point, opts ...grpc.CallOption) (*Feature, error) {
	out := new(Feature)
	err := c.cc.Invoke(ctx, "/routeguide.RouteGuide/GetFeature", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *routeGuideClient) ListFeatures(ctx context.Context, in *Rectangle, opts ...grpc.CallOption) (RouteGuide_ListFeaturesClient, error) {
	stream, err := c.cc.NewStream(ctx, &_RouteGuide_serviceDesc.Streams[0], "/routeguide.RouteGuide/ListFeatures", opts...)
	if err != nil {
		return nil, err
	}
	x := &routeGuideListFeaturesClient{stream}
	if err := x.ClientStream.SendMsg(in); err != nil {
		return nil, err
	}
	if err := x.ClientStream.CloseSend(); err != nil {
		return nil, err
	}
	return x, nil
}

type RouteGuide_ListFeaturesClient interface {
	Recv() (*Feature, error)
	grpc.ClientStream
}

type routeGuideListFeaturesClient struct {
	grpc.ClientStream
}

func (x *routeGuideListFeaturesClient) Recv() (*Feature, error) {
	m := new(Feature)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

func (c *routeGuideClient) RecordRoute(ctx context.Context, opts ...grpc.CallOption) (RouteGuide_RecordRouteClient, error) {
	st
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值