如何使用Golang实现RPC序列化与反序列化_Golang RPC数据编码与解码方法


net/rpc 默认用 gob,不支持跨语言;换 JSON 需用 jsonrpc 包并调用 jsonrpc.ServeConn;换 protobuf 应直接用 gRPC;自定义 ServerCodec 必须处理分帧、Header 解析和错误传播。

Go 标准库的 net/rpc 默认使用 gob 编码,不支持跨语言、不兼容 JSON 或 Protocol Buffers——如果你需要自定义序列化(比如用 jsonprotobuf),必须绕过默认机制,自己接管编解码流程。

为什么不能直接替换 rpc.Server 的编解码器?

标准 rpc.Serverrpc.Client 将编码/解码深度耦合在 rpc.Server.ServeCodecrpc.NewClientWithCodec 中,底层依赖 rpc.ServerCodec 接口。它要求你同时实现 ReadRequestHeader/ReadRequestBodyWriteResponse 等方法,不能只换一个序列化格式。

常见错误是试图“简单替换 gobjson”,结果发现请求头读不出来、响应乱序、或连接直接断开——因为 json 没有 gob 那样的类型元信息和流式分帧能力。

  • gob 自带类型描述、支持指针/接口/循环引用,且天然适配 Go 运行时;json 是纯文本、无类型、需显式结构体标签
  • RPC 协议不是“发一串 JSON 就完事”,它需要严格区分 header(含方法名、序列号)和 body(参数),而 json 不提供内置分界机制
  • 标准 rpc/jsonrpc 包只是对 gob 编解码逻辑的重写,并非“用 encoding/json 替代 gob”——它仍遵循 RPC 帧格式约定

如何用 json 实现兼容标准 rpc.Client 的服务端?

使用 net/rpc/jsonrpc 是最轻量、最兼容的方式:它复用了标准 rpc 的注册与调用逻辑,仅替换底层编解码器。客户端无需改代码,只要把 rpc.NewClient 换成 jsonrpc.NewClient 即可。

服务端启动示例:

package main

import ( "net" "net/rpc" "net/rpc/jsonrpc" )

type Args struct{ A, B int } type Quotient struct{ Quo, Rem int }

type Arith int

func (t Arith) Multiply(args Args, reply int) error { reply = args.A * args.B return nil }

func main() { rpc.Register(new(Arith)) listener, := net.Listen("tcp", ":1234") for { conn, := listener.Accept() go jsonrpc.ServeConn(conn) // ← 关键:用 jsonrpc.ServeConn 替代 rpc.ServeConn } }

注意点:

  • 必须用 jsonrpc.ServeConn 启动连接,不能用 rpc.ServeConn
  • 客户端必须用 jsonrpc.NewClientjsonrpc.Dial,否则会因帧格式不匹配而报 invalid character 错误
  • 结构体字段必须首字母大写(导出),且建议加 json: 标签以控制 key 名

如何用 protobuf + gRPC 替代原生 net/rpc

如果你真正想要的是高性能、跨语言、带 IDL 的 RPC,不要硬改 net/rpc,直接用 gRPC-Go。它本质是基于 HTTP/2 的二进制 RPC 框架,protobuf 是其默认序列化协议,天然支持 streaming、拦截器、超时、认证等。

关键区别:

  • net/rpc 是 TCP + 自定义二进制帧(gob)或 JSON 帧;gRPC 是 HTTP/2 + protobuf + gRPC-encoding(length-delimited)
  • gRPC 要求先写 .proto 文件生成 Go 代码;net/rpc 直接注册结构体和方法
  • 没有 gRPC 服务端,protobuf 只是序列化工具——你仍需自己设计传输层(比如用 net.Conn + 自定义分帧),这极易出错

所以,除非你有强约束(如必须复用现有 net/rpc 客户端、不能引入新协议栈),否则别尝试“给 net/rpc 换 protobuf 底层”。真要这么做,得完整实现 rpc.ServerCodec,包括:ReadRequestHeader 解析 method/service/seq,ReadRequestBodyproto.Unmarshal,还要处理 length-prefix framing——这已接近重写整个 RPC 栈。

自定义编解码器时最容易忽略的细节

当你实现自己的 rpc.ServerCodec,以下三点几乎必踩坑:

  • TCP 是字节流,没有消息边界——必须自己加长度前缀(如 4 字节 uint32 表示后续 payload 长度),否则 ReadRequestBody 会阻塞或读错数据
  • ReadRequestHeader 必须严格按 RPC 协议解析出 ServiceMethod 字符串(格式为 "Service.Method")和 Seq(请求序号),漏掉任一字段会导致客户端永远收不到响应
  • WriteResponseerr 参数不能忽略:如果业务逻辑返回 error,必须写入 response body 并设置 ErrorResponse 标志,否则客户端 Call 会卡死或 panic

真正稳定的自定义方案,往往不是从零写 ServerCodec,而是基于 gRPCCodec 接口或 go-microcodec 插件机制——它们已封装好分帧、上下文、错误传播等细节。


# js  # json  # go  # golang  # 编码  # 字节  # 工具  #   # ai  # stream  # 区别  # 标准库  # 为什么  # 封装  # Error  # 字符串  # 结构体  # 无类型  # 循环  # 指针  # 接口  # Length  # http  # rpc  # 自定义  # 客户端  # 如果你  # 序列化  # 服务端  # 重写  # 不支持  # 编解码器  # 如何用  # 如用 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334


相关推荐: Win11任务栏怎么调到左边_Win11开始菜单居左设置教程【步骤】  Python与Docker容器化部署实战_镜像构建与CI/CD流程  Win11怎么关闭定位服务_保护Win11位置隐私设置指南【详解】  c++如何打印函数堆栈信息_c++ backtrace函数与符号名解析【方法】  Python异步编程高级项目教程_asyncio协程任务管理实战  c++ atoi和atof函数用法_c++字符数组转数字  Win11蓝牙开关不见了怎么办_Win11蓝牙驱动丢失修复教程【方法】  Win11麦克风没声音怎么设置_Win11麦克风权限及驱动修复【教程】  php中$this和::能混用吗_对象与静态作用域冲突解决【方法】  如何将竖排文本文件转换为横排字符串  如何在包含多值的列中精准搜索指定演员?  Win11怎么激活Windows10_Win11激活Win10系统方法【步骤】  Windows10系统怎么查看硬盘健康_Win10 SMART信息检测工具  Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置  Python邮件系统自动化教程_批量发送解析与模板应用  php和redis连接超时怎么办_phpredis调试连接问题汇总【指南】  php转exe用什么工具打包快_高效打包软件推荐【汇总】  Windows10任务栏图标变成白色文件_Win10重建图标缓存修复方法  为什么Go需要go mod文件_Go go mod文件作用说明  Windows10如何更改系统字体大小_Win10辅助功能文本缩放设置  如何在Golang中捕获HTTP服务器错误_GolangHTTP Handler中error处理  如何解决同一段404代码在不同主机上表现不一致的问题  如何在Golang中处理二进制数据_Golang io与encoding/binary二进制操作方法  Mac电脑如何恢复出厂设置_Mac抹掉数据并重装系统【安全指南】  如何使用Golang搭建本地API测试环境_快速验证接口功能  php错误怎么开启_display_errors与log_errors的设置【汇总】  Win11怎么恢复旧版开始菜单_通过软件还原Win10风格菜单【详解】  Python异步网络编程_aiohttp说明【指导】  如何在Golang中编写端到端测试_Golang E2E测试流程示例  Win10如何更改网络连接_Windows10以太网属性IP配置  Win11怎么更改电脑密码_Windows 11修改本地账户密码【步骤】  如何在 Windows 11 中使用 AlomWare 工具箱  Windows蓝屏错误0x00000018怎么处理_驱动初始化错误解决  Win11如何设置系统声音_Win11系统声音调整教程【攻略】  如何在 ACF 中正确更新嵌套多层的 Group 字段子字段  Windows10如何更改鼠标灵敏度_Win10鼠标属性指针选项调节  Win11如何开启telnet服务 Win11启用Telnet客户端【步骤】  如何在Golang中指定模块版本_使用go.mod控制版本号  Windows10如何更改任务栏高度_Win10解除锁定调整大小  Python网络超时处理_健壮性设计说明【指导】  Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】  Win11系统更新后黑屏怎么办 Win11更新黑屏修复教程【方法】  如何在Golang中实现服务熔断与限流_Golang微服务容错与流控方法  c++中如何求一个数的平方根_c++ sqrt函数与牛顿迭代法  PythonDocker高级项目部署教程_多容器管理与CI/CD流水线  如何使用Golang实现路由分组管理_Golang路由分组与权限控制方法  Win11怎么开启游戏工具栏_Windows11 Xbox Game Bar快捷键  Go 中实现 Python urllib.quote() 等效功能的正确方式  php中作用域操作符能访问私有静态属性吗_访问权限限制【指南】  Win11鼠标灵敏度怎么调 Win11鼠标指针移动速度设置【教程】 

 2026-01-01

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

致胜网络推广营销网


致胜网络推广营销网

致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 915688610

 17370845950

 915688610@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.