首页 > 后端开发 > Golang > 正文

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

P粉602998670
发布: 2025-09-06 10:27:03
原创
580人浏览过
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: " 前缀的消息回传给客户端。

微信 WeLM
微信 WeLM

WeLM不是一个直接的对话机器人,而是一个补全用户输入信息的生成模型。

微信 WeLM 33
查看详情 微信 WeLM

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 压缩。

以上就是GolangRPC流式传输与双向通信示例的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

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