IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> gRPC的四种数据流 -> 正文阅读

[网络协议]gRPC的四种数据流

1、简介

srteam 顾名思义就是一种流,可以源源不断的推送数据,很适合传输一些大数据,或者服务端和客户端长时间数据交互,比如客户端可以向服务端订阅一个数据,服务端就可以利用stream ,源源不断地推送数据。

2、四种流模式

2.1 简单模式(Simple RPC)

这种模式最为传统,即客户端发起一次请求,服务端响应一个数据,这和大家平时熟悉的RPC没有什么大的区别,所以不再详细介绍。

2.2 服务端数据流模式(Server-side streaming RPC)

这种模式是客户端发起一次请求,服务端返回一段连续的数据流。典型的例子是客户端向服务端发送一个股票代码,服务端就把该股票的实时数据源源不断的返回给客户端。

2.3 客户端数据流模式(Client-side streaming RPC)

与服务端数据流模式相反,这次是客户端源源不断的向服务端发送数据流,而在发送结束后,由服务端返回一个响应。典型的例子是物联网终端向服务器报送数据。

2.4 双向数据流模式(Bidirectional streaming RPC)

顾名思义,这是客户端和服务端都可以向对方发送数据流,这个时候双方的数据可以同时互相发送,也就是可以实现实时交互。典型的例子是聊天机器人。

3、定义protobuf文件

syntax = "proto3";

option go_package = "../proto";

service Greeter{
  // 服务端流模式
  rpc GetStream(StreamReqData) returns(stream StreamResData);
  // 客户端流模式
  rpc PutStream(stream StreamReqData)returns(StreamResData);
  // 双向流模式
  rpc AllStream(stream StreamReqData)returns(stream StreamResData);
}

message StreamReqData{
  string data = 1;
}

message StreamResData{
  string data = 1;
}

4、生成go的rpc文件

protoc -I . goods.proto --go_out=plugins=grpc:.

服务端

server.go

package main

import (
	"demo/stream_grpc_test/proto"
	"fmt"
	"google.golang.org/grpc"
	"net"
	"sync"
	"time"
)

const PORT = "0.0.0.0:8080"

type Server struct {
}

// GetStream 服务端流模式
func (s *Server) GetStream(req *proto.StreamReqData, res proto.Greeter_GetStreamServer) error {
	i := 0
	for {
		i++
		_ = res.Send(&proto.StreamResData{Data: fmt.Sprintf("%v", time.Now().Unix())})
		time.Sleep(1 * time.Second)
		if i > 10 {
			break
		}
	}

	return nil
}

// PutStream 客户端流模式
func (s *Server) PutStream(cliStr proto.Greeter_PutStreamServer) error {
	for {
		if tem, err := cliStr.Recv(); err == nil {
			fmt.Println(tem)
		} else {
			fmt.Println("break, err :", err)
			break
		}
	}
	return nil
}

// AllStream 双向流模式
func (s *Server) AllStream(allStr proto.Greeter_AllStreamServer) error {
	wg := sync.WaitGroup{}
	wg.Add(2)

	go func() {
		defer wg.Done()
		for i := 0; i < 10; i++ {
			data, _ := allStr.Recv()
			fmt.Println(data)
		}
	}()

	go func() {
		defer wg.Done()
		for i := 0; i < 5; i++ {
			_ = allStr.Send(&proto.StreamResData{
				Data: "jason",
			})
			
			time.Sleep(1 * time.Second)
		}
	}()

	wg.Wait()

	return nil
}

func main() {
	lis, err := net.Listen("tcp", PORT)
	if err != nil {
		panic(err)
	}
	// 创建一个grpc 服务器
	s := grpc.NewServer()
	// 注册事件
	proto.RegisterGreeterServer(s, &Server{})
	// 处理链接
	err = s.Serve(lis)
	if err != nil {
		panic(err)
	}
}

服务端流模式的客户端

client.go

package main

import (
	"context"
	"demo/stream_grpc_test/proto"
	"fmt"
	"google.golang.org/grpc"
	"time"
)

const ADDRESS = "127.0.0.1:8080"

func main() {
	// 通过grpc库建立连接
	conn, err := grpc.Dial(ADDRESS, grpc.WithInsecure())
	if err != nil {
		panic(err.Error())
	}
	defer func() {
		_ = conn.Close()
	}()

	// 获取client对象
	c := proto.NewGreeterClient(conn)

	// 调用服务端推送流
	res, err := c.GetStream(context.Background(), &proto.StreamReqData{Data: "aaa"})
	if err != nil {
		panic(err.Error())
	}
	for {
		getData, err := res.Recv()
		if err != nil {
			fmt.Println(err)
			break
		}

		fmt.Println(getData)
	}

	// 延迟,防止程序直接退出
	time.Sleep(30 * time.Second)
}

在这里插入图片描述

客户端流模式的客户端

client.go

package main

import (
	"context"
	"demo/stream_grpc_test/proto"
	"google.golang.org/grpc"
	"time"
)

const ADDRESS = "127.0.0.1:8080"

func main() {
	// 通过grpc库建立连接
	conn, err := grpc.Dial(ADDRESS, grpc.WithInsecure())
	if err != nil {
		panic(err.Error())
	}
	defer func() {
		_ = conn.Close()
	}()

	// 获取client对象
	c := proto.NewGreeterClient(conn)

	// 客户端推送流
	putRes, err := c.PutStream(context.Background())
	for i := 0; i < 10; i++ {
		_ = putRes.Send(&proto.StreamReqData{Data: "zhou"})
		time.Sleep(1 * time.Second)
	}

	// 延迟,防止程序直接退出
	time.Sleep(30 * time.Second)
}

在这里插入图片描述

双向流模式的客户端

client.go

package main

import (
	"context"
	"demo/stream_grpc_test/proto"
	"fmt"
	"google.golang.org/grpc"
	"time"
)

const ADDRESS = "127.0.0.1:8080"

func main() {
	// 通过grpc库建立连接
	conn, err := grpc.Dial(ADDRESS, grpc.WithInsecure())
	if err != nil {
		panic(err.Error())
	}
	defer func() {
		_ = conn.Close()
	}()

	// 获取client对象
	c := proto.NewGreeterClient(conn)

	// 双向流
	allStr, err := c.AllStream(context.Background())
	if err != nil {
		panic(err.Error())
	}
	go func() { // 接收服务端推送的数据
		for {
			data, _ := allStr.Recv()
			fmt.Println("接收数据:" + (*data).Data)
		}
	}()

	go func() { // 发送数据到服务端
		for {
			err = allStr.Send(&proto.StreamReqData{Data: "我来自发送"})
			if err != nil {
				fmt.Println(err.Error())
				break
			}
			time.Sleep(1 * time.Second)
		}
	}()

	// 延迟,防止程序直接退出
	time.Sleep(30 * time.Second)
}

在这里插入图片描述
在这里插入图片描述

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-12-11 16:04:59  更:2021-12-11 16:06:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:29:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码