新闻中心

Golang如何使用gRPC实现双向流通信_Golang gRPC双向流通信实践详解

2025-11-25
浏览次数:
返回列表
首先定义支持双向流的.proto文件,生成Go代码后分别实现服务器和客户端逻辑,通过stream.Send和stream.Recv实现全双工通信。

golang如何使用grpc实现双向流通信_golang grpc双向流通信实践详解

在Go语言中使用gRPC实现双向流通信,可以高效地处理客户端与服务器之间持续交互的场景,比如实时聊天、日志推送、监控系统等。gRPC基于HTTP/2协议,天然支持双向流(Bidirectional Streaming),允许客户端和服务器同时发送多个消息,形*双工通信。

定义.proto文件支持双向流

要实现双向流通信,首先需要在.proto文件中定义一个服务方法,其请求和响应都使用stream关键字。

示例:chat.proto

syntax = "proto3";

package chat;

service ChatService {
rpc ChatStream(stream Message) returns (stream Message);
}

message Message {
string user = 1;
string content = 2;
}

这里ChatStream方法接收一个流式的Message,并返回一个流式的Message,表示客户端和服务器都可以连续发送消息。

生成Go代码

使用protoc配合gRPC插件生成Go代码:

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

会生成chat.pb.go文件,包含服务接口和数据结构定义。

实现服务器端逻辑

服务器需实现服务接口,并在处理函数中通过stream.Recv()接收消息,用stream.Send()发送消息。

美图云修 美图云修

商业级AI影像处理工具

美图云修 50 查看详情 美图云修

示例服务器代码:

func (s *ChatServer) ChatStream(stream chat.ChatService_ChatStreamServer) error {
  for {
    msg, err := stream.Recv()
    if err == io.EOF {
      return nil
    }
    if err != nil {
      return err
    }

    // 处理消息,可广播给其他客户端
    response := &chat.Message{
      User: "Server",
      Content: "Echo: " + msg.Content,
    }

    stream.Send(response)
  }
}

注意:服务器在Recv遇到io.EOF时表示客户端关闭了发送流。

实现客户端逻辑

客户端通过调用ChatStream获得一个流对象,使用SendRecv与服务器通信。

示例客户端代码:

stream, _ := client.ChatStream(context.Background())

// 开启goroutine接收服务器消息
go func() {
  for {
    msg, err := stream.Recv()
    if err == io.EOF {
      break
    }
    if err != nil {
      log.Fatal(err)
    }
    fmt.Printf("收到: %s - %s\n", msg.User, msg.Content)
  }
}()

// 发送消息
for i := 0; i   msg := &chat.Message{User: "Client", Content: fmt.Sprintf("消息 %d", i)}
  stream.Send(msg)
  time.Sleep(time.Second)
}

stream.CloseSend()

客户端使用独立的goroutine接收消息,避免阻塞发送流程。调用CloseSend通知服务器不再发送数据。

基本上就这些。只要.proto定义正确,收发逻辑清晰,gRPC的双向流在Go中使用非常直接。关键是理解流的生命周期和EOF的处理。实际项目中可结合上下文取消、超时控制和连接复用提升稳定性。

以上就是Golang如何使用gRPC实现双向流通信_Golang gRPC双向流通信实践详解的详细内容,更多请关注其它相关文章!


# 多个  # 网站站内外优化  # 网站建设推广推荐 LS15227优秀  # 安平网络营销策划推广  # 营销推广费编号  # 矩阵seo筑榜  # 修文网站seo优化价格  # Js渲染seo  # 生命十大关键词排名图片  # 优化网站程序  # 鹤壁做推广网站的公司  # 相关文章  # 并在  # go  # 全双工  # 流式  # 发送消息  # 如何使用  # 数据结构  # 美图  # 客户端  # 实时聊天  # stream  # go语言  # golang 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 2306选座时如何选靠窗位置_12306选座靠窗座位查看方法解析  wps文字怎么插入目录并自动更新_wps文字如何插入目录并自动更新方法  响应式容器内容自动缩放与宽高比维持教程  QQ邮箱网页版入口页面 QQ邮箱在线登录入口官网  12306选座怎么选到临时改签座_12306改签选座策略与步骤  2025年云电脑操作系统体验 | 无需本地硬件,随时随地使用高性能PC  qq游戏跨平台入口_qq游戏多设备同步登录  可靠CSGO开箱平台解析 CSGO开箱网合集  如何在Promise链中有效终止错误处理后的执行  谷歌浏览器浏览体验优化_谷歌浏览器新版直连永久可用提示  c++如何实现单例设计模式_c++线程安全的单例模式写法  J*a TimerTask文件监控:HashMap状态管理与常见陷阱规避指南  如何修改开机登录密码_Windows账户安全设置超详细教程【必学】  Lar*el Excel导入时生成自定义递增ID的策略与实践  如何使用Node.js csv 包按条件移除含空字段的CSV记录  魅族17怎样用浏览器译外语网页_iPhone魅族17浏览器译外语网页【即时翻译】  《明末:渊虚之羽》设计师谈设计角色:那会刚毕业 充满激情  优化MinIO list_objects_v2 操作的性能瓶颈与最佳实践  铁路12306卧铺选择攻略 铁路12306下铺座位预定技巧  Lar*el递归关系中排除子孙节点的策略  J*aScript井字棋(Tic-Tac-Toe)核心交互逻辑实现教程  12306几点到几点不能订票? | 官方最新系统维护时间全解析  AO3最新镜像入口 Archive of Our Own官方平台访问  2026年CSGO开箱网站推荐 CSGO开箱平台精选  LINUX下如何进行磁盘分区_fdisk与parted工具在LINUX中的使用对比  苹果手机如何防止被恶意App追踪  初次安装JDK时环境变量如何正确配置_J*A_HOME与PATH设置规则讲解  为什么简单的XML文件也会解析失败? 检查隐藏的非打印字符(如BOM)的方法  Spring Boot内嵌服务器与J*a EE全栈特性:选择与部署策略  C++如何比较两个字符串_C++ string compare函数与操作符对比  如何高效处理PHP中的Excel数据导入导出?PortPHP/Spreadsheet助你轻松搞定!  TikTok搜索结果不显示如何解决 TikTok搜索刷新优化方法  C#中解析不规范的HTML为XML 常见的坑与解决办法  《铁拳8》黑皮辣妹新实机:元气满满的18岁少女!  AI泡沫首次被“刺破”:GPU十年都无法存活!  Web Components中自定义开关组件状态同步的常见陷阱与解决方案  支付宝解绑银行卡步骤_支付宝如何解除绑定银行卡  生成rdflib自定义SPARQL函数:参数匹配与实践指南  qq邮箱发邮件给国外发不出去_QQ邮箱国际邮件发送失败原因与解决  Node.js CSV 数据处理:基于字段空值条件过滤整条记录的策略  Lar*el DB::listen 事件中的查询执行时间单位解析  QQ邮箱网页版登录入口 QQ邮箱官方在线使用平台  在VS Code中配置和运行Dart程序的完整步骤  cad如何更改注释性对象的比例_cad注释性比例调整方法  J*a递归快速排序中静态变量导致数据累积的陷阱与解决方案  J*aScript中管理异步API调用:确保操作顺序与数据一致性  Win11如何使用Windows Sandbox Win11沙盒功能开启与使用教程【详解】  深入理解Go语言中的指针类型:以*string为例  CSS Flexbox与媒体查询:实现响应式布局中元素的并排与堆叠  文本文档写html代码怎么运行_文本文档html代码运行步骤【教程】 

搜索