gRPC流模式的实现和TLS加密通信[Go和asp.net core 5.0]

本文介绍了gRPC的四种通信模式,并通过Go和ASP.NET Core 5.0展示了如何实现客户端流、服务端流和双向流。在Go中详细阐述了服务端和客户端的代码实现,接着在ASP.NET Core 5.0中展示了TLS加密通信的配置。提供相关代码示例和运行结果,以及证书生成工具的链接。
摘要由CSDN通过智能技术生成

gRPC主要有4种请求和响应模式,分别是简单模式(Simple RPC)服务端流式(Server-side streaming RPC)客户端流式(Client-side streaming RPC)、和双向流式(Bidirectional streaming RPC)

1.简单模式(Simple RPC):客户端发起请求并等待服务端响应。

2.服务端流式(Server-side streaming RPC):客户端发送请求到服务器,拿到一个流去读取返回的消息序列。 客户端读取返回的流,直到里面没有任何消息。 场景:.客户端要获取某原油股的实时走势,客户端发送一个请求, 服务端实时返回该股票的走势

3.客户端流式(Client-side streaming RPC):与服务端数据流模式相反,这次是客户端源源不断的向服务端发送数据流,而在发送结束后,由服务端返回一个响应。情景模拟:客户端大量数据上传到服务端

4.双向流式(Bidirectional streaming RPC):双方使用读写流去发送一个消息序列,两个流独立操作,双方可以同时发送和同时接收。 情景模拟:双方对话(可以一问一答、一问多答、多问一答,形式灵活)

从上面的定义不难看出,用stream可以定义一个流式消息。下面我们就通过实例来演示一下流式通信的使用方法。

GO

1.首先/api/hello.proto [如下], 并且生成新的api/hello.pb.go代码。

syntax = "proto3";

package api;
// Any消息类型允许您将消息作为嵌入类型,而不需要它们 .proto定义。Any包含任意序列化的消息(字节),以及一个URL,该URL充当该消息的全局唯一标识符并解析为该消息的类型。要使用Any类型,你需要导入google/protobuf/any.proto.
import "google/protobuf/any.proto";

message HelloRequest {
  string greeting = 1;
  map<string, string> infos  = 2;
}

message HelloResponse {
  string reply = 1;
  repeated google.protobuf.Any details = 2;
}

service HelloService {
  rpc SayHello(HelloRequest) returns (HelloResponse){}
  rpc ListHello(HelloRequest) returns (stream HelloResponse) {}
  rpc SayMoreHello(stream HelloRequest) returns (HelloResponse) {}
  rpc SayHelloChat(stream HelloRequest) returns (stream HelloRequest) {}
}

message Hello {
	string msg = 1;
}

message Error {
	repeated string msg = 1;
}

2.编译指令:

protoc -ID:\Go\include -I. --go_out=plugins=grpc:. ./api/api.proto

3.在生成的代码api.hello.go中,我们可以看到客户端接口如下:

type HelloServiceServer interface {
	SayHello(context.Context, *HelloRequest) (*HelloResponse, error)
	ListHello(*HelloRequest, HelloService_ListHelloServer) error
	SayMoreHello(HelloService_SayMoreHelloServer) error
	SayHelloChat(HelloService_SayHelloChatServer) error
}

4.接口的实现 server/service/service.go如下:

package service

import (
	"context"
	"fmt"
	"io"
	"log"
	"time"

	"github.com/golang/protobuf/ptypes"
	"github.com/golang/protobuf/ptypes/any"

	api "gogrpcstream/api"
)

type SayHelloServer struct{}

func (s *SayHelloServer) SayHello(ctx context.Context, in *api.HelloRequest) (res *api.HelloResponse, err error) {
	log.Printf("Client Greeting:%s", in.Greeting)
	log.Printf("Client Info:%v", in.Infos)

	var an *any.Any
	if in.Infos["hello"] == "world" {
		an, err = ptypes.MarshalAny(&api.Hello{Msg: "Good Request"})
	} else {
		an, err = ptypes.MarshalAny(&api.Error{Msg: []string{"Bad Request", "Wrong Info Msg"}})
	}

	if err != nil {
		return
	}
	return &api.HelloResponse{
		Reply:   "Hello World !!",
		Details: []*any.Any{an},
	}, nil
}

// 服务器端流式 RPC, 接收一次客户端请求,返回一个流
func (s *SayHelloServer) ListHello(in *api.HelloRequest, stream api.HelloService_ListHelloServer) error {
	log.Printf("Client Say: %v", in.Greeting)

	stream.Send(&api.HelloResponse{Reply: "ListHello Reply " + in.Greeting + " 1"})
	time.Sleep(1 * time.Second)
	stream.Send(&api.HelloResponse{Reply: "ListHello Reply " + in.Greeting + " 2"})
	time.Sleep(1 * time.Second)
	stream.Send(&api.HelloResponse{Reply: "ListHello Reply " + in.Greeting + " 3"})
	time.Sleep(1 * time.Second)
	return nil
}

// 客户端流式 RPC, 客户端流式请求,服务器可返回一次
func (s *SayHelloServer) SayMoreHello(stream api.HelloService_SayMoreHelloServer) error {
	// 接受客户端请求
	for {
		req, err := stream.Recv()
		if err == io.EOF {
			break
		}

		if err != nil {
			return err
		}

		log.Printf("SayMo
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值