0

0

GolangRPC流式传输与双向通信示例

P粉602998670

P粉602998670

发布时间:2025-09-06 10:27:03

|

595人浏览过

|

来源于php中文网

原创

Golang gRPC双向流式传输支持实时交互,通过定义protobuf服务、生成代码、实现服务器和客户端完成通信,示例中客户端发送消息服务器回显;需处理流中错误,可采用重试或断路器模式;通过TLS和JWT实现身份验证与授权;性能优化包括启用压缩、调整缓冲区、使用连接池、负载均衡及HTTP/3协议提升传输效率。

golangrpc流式传输与双向通信示例

Golang gRPC 流式传输允许客户端和服务器之间进行连续的数据交换,而不仅仅是传统的请求-响应模式。双向流式传输则允许双方同时发送和接收数据,极大地增强了实时性和交互性。

解决方案

下面是一个简单的 Golang gRPC 双向流式传输的示例。

1. 定义 Protocol Buffer (protobuf) 服务

立即学习go语言免费学习笔记(深入)”;

首先,我们需要定义一个 protobuf 文件,描述我们的服务和消息格式。

syntax = "proto3";

package stream;

option go_package = "./stream";

service StreamService {
  rpc RouteChat (stream RouteNote) returns (stream RouteNote) {}
}

message RouteNote {
  string message = 1;
}

这个protobuf文件定义了一个

StreamService
服务,其中包含一个
RouteChat
方法。
RouteChat
方法接受并返回
RouteNote
类型的流。

2. 生成 gRPC 代码

使用

protoc
命令编译 protobuf 文件,生成 Golang 代码。

protoc --go_out=. --go-grpc_out=. stream.proto

这将生成

stream.pb.go
stream_grpc.pb.go
文件。

3. 实现 gRPC 服务器

接下来,我们需要实现 gRPC 服务器。

package main

import (
    "context"
    "fmt"
    "io"
    "log"
    "net"

    "google.golang.org/grpc"
    "google.golang.org/grpc/reflection"
    pb "example.com/stream" // 替换成你的模块路径
)

type server struct {
    pb.UnimplementedStreamServiceServer
}

func (s *server) RouteChat(stream pb.StreamService_RouteChatServer) error {
    for {
        note, err := stream.Recv()
        if err == io.EOF {
            return nil
        }
        if err != nil {
            return err
        }
        log.Printf("Received message: %v", note.Message)

        // Echo back the message
        resp := &pb.RouteNote{Message: "Server received: " + note.Message}
        if err := stream.Send(resp); err != nil {
            return err
        }
    }
}

func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterStreamServiceServer(s, &server{})
    reflection.Register(s)
    fmt.Println("Server listening on :50051")
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

这段代码创建了一个 gRPC 服务器,监听 50051 端口,并注册了

StreamService
服务。
RouteChat
方法循环接收客户端发送的消息,并将带有 "Server received: " 前缀的消息回传给客户端。

Cutout.Pro抠图
Cutout.Pro抠图

AI批量抠图去背景

下载

4. 实现 gRPC 客户端

现在,我们需要实现 gRPC 客户端。

package main

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

    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
    pb "example.com/stream" // 替换成你的模块路径
)

func main() {
    conn, err := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials()))
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()

    client := pb.NewStreamServiceClient(conn)

    stream, err := client.RouteChat(context.Background())
    if err != nil {
        log.Fatalf("could not greet: %v", err)
    }

    // Send messages
    messages := []string{"Hello", "World", "How", "Are", "You"}
    for _, message := range messages {
        req := &pb.RouteNote{Message: message}
        if err := stream.Send(req); err != nil {
            log.Fatalf("failed to send a note: %v", err)
        }
        log.Printf("Sent message: %v", message)
        time.Sleep(time.Second) // Simulate some delay
    }

    // Close the stream and receive responses
    if err := stream.CloseSend(); err != nil {
        log.Fatalf("failed to close stream: %v", err)
    }

    for {
        resp, err := stream.Recv()
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Fatalf("failed to receive a note: %v", err)
        }
        log.Printf("Received message: %v", resp.Message)
    }

    fmt.Println("Client finished")
}

这段代码连接到 gRPC 服务器,创建

StreamService
客户端,并调用
RouteChat
方法。客户端发送一系列消息,然后关闭发送流,并接收服务器返回的消息。

5. 运行示例

首先,启动 gRPC 服务器。

go run server.go

然后,启动 gRPC 客户端。

go run client.go

你将在服务器和客户端的控制台中看到消息的发送和接收。

如何处理 gRPC 流中的错误?

在流式传输中,错误处理至关重要。服务器和客户端都需要能够优雅地处理连接中断、数据损坏或其他意外情况。在服务器端,

RouteChat
函数的循环中,我们检查
stream.Recv()
stream.Send()
的返回值,如果遇到错误,则立即返回。客户端也做了类似的错误处理。 更复杂的错误处理可能涉及到自定义错误类型、重试机制或断路器模式。例如,可以定义一个专门的错误类型,用于表示流式传输中的特定错误,并根据错误类型采取不同的处理策略。

如何在 gRPC 流中进行身份验证和授权?

安全性是另一个需要考虑的重要方面。gRPC 提供了多种身份验证机制,例如 TLS、JWT 和自定义身份验证。对于流式传输,通常使用 TLS 来加密通信,并使用 JWT 或其他身份验证方法来验证客户端的身份。服务器可以在

RouteChat
函数中验证客户端提供的身份验证信息,并根据用户的角色和权限来决定是否允许客户端访问资源。例如,可以创建一个 gRPC 拦截器,用于在每个流式请求上验证 JWT 令牌。

如何优化 gRPC 流的性能?

gRPC 流的性能受到多种因素的影响,例如网络延迟、消息大小和服务器的负载。为了优化性能,可以采取以下措施:

  • 使用压缩: 启用 gRPC 的压缩功能可以减少消息的大小,从而提高传输速度。
  • 调整缓冲区大小: 调整 gRPC 的发送和接收缓冲区大小可以优化内存使用和吞吐量。
  • 使用连接池: 使用连接池可以减少连接建立的开销,从而提高性能。
  • 负载均衡: 使用负载均衡可以将请求分发到多个服务器上,从而提高系统的可用性和可扩展性。
  • 协议选择: 考虑使用 HTTP/3 协议,它在拥塞控制和多路复用方面提供了改进,尤其是在高延迟或丢包的网络环境下。HTTP/3 默认使用 QUIC 协议,提供更好的连接迁移能力。

例如,可以通过设置

grpc.WithDefaultCallOptions(grpc.UseCompressor(gzip.Name))
来启用 gzip 压缩。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

174

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

224

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

335

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

206

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

388

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

193

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

188

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

191

2025.06.17

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
golang socket 编程
golang socket 编程

共2课时 | 0.1万人学习

nginx浅谈
nginx浅谈

共15课时 | 0.8万人学习

golang和swoole核心底层分析
golang和swoole核心底层分析

共3课时 | 0.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号