本文详解如何使用 curl 等通用 HTTP 工具跨语言调用 Go net/rpc 服务,重点基于 rpc/jsonrpc 实现的 JSON-RPC 1.0 协议,涵盖请求构造、序列化规则、常见错误及最佳实践。
本文详解如何使用 curl 等通用 http 工具跨语言调用 go `net/rpc` 服务,重点基于 `rpc/jsonrpc` 实现的 json-rpc 1.0 协议,涵盖请求构造、序列化规则、常见错误及最佳实践。
Go 标准库的 net/rpc 默认采用自定义二进制协议(Gob),不兼容 HTTP 直接交互。若需通过 curl 或其他非 Go 客户端调用,必须启用 rpc/jsonrpc 子包提供的 JSON-RPC 1.0 支持——它将 RPC 请求/响应封装为标准 JSON 格式,并通过 HTTP POST(而非 CONNECT)传输。
✅ 正确的服务端配置(关键前提)
首先,服务端需显式注册 JSON-RPC 处理器,而非默认的 Gob RPC:
package main
import (
"log"
"net/http"
"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))
rpc.HandleHTTP() // 注册 /_goRPC 路由(用于 Gob)
// ✅ 关键:为 JSON-RPC 单独注册处理器
http.Handle("/_goRPC_", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 设置 Content-Type 避免客户端解析失败
w.Header().Set("Content-Type", "application/json")
jsonrpc.ServeHTTP(w, r)
}))
log.Println("RPC server listening on :1234")
log.Fatal(http.ListenAndServe(":1234", nil))
}⚠️ 注意:/_goRPC_(末尾带下划线)是 Go jsonrpc 包约定的默认路径,不可省略或修改;而 /_goRPC(无下划线)仅用于 Gob 协议,curl 无法直接通信。
✅ 正确的 curl 请求格式(POST + JSON)
curl 必须使用 POST 方法(不是 CONNECT),并发送符合 JSON-RPC 1.0 规范的请求体:
curl -X POST \
--url http://localhost:1234/_goRPC_ \
-H "Content-Type: application/json" \
-d '{
"method": "Arith.Multiply",
"params": [{"A": 7, "B": 3}],
"id": 1
}'响应示例:
{"id":1,"result":21,"error":null}? 字段说明:
- method: 完整方法名,格式为 "StructName.MethodName"(区分大小写);
- params: 数组,即使只有一个参数也需包裹成数组;结构体参数需为 JSON 对象(如 {"A":7,"B":3}),基础类型可直接传值(如 [7,3],但需服务端方法签名匹配);
- id: 任意 JSON 值(数字、字符串均可),用于客户端匹配响应,不可省略;
- Content-Type 必须显式设置为 application/json,否则 Go 的 jsonrpc 会返回 404。
❌ 常见错误与排查
| 错误现象 | 原因 | 解决方案 |
|---|---|---|
| 404 Not Found | 访问了 /_goRPC(Gob 路径)或路径拼写错误 | 确认使用 /_goRPC_,且服务端已注册该路由 |
| 500 Internal Server Error | params 类型与 Go 方法签名不匹配(如传字符串但期望 *Args) | 检查 params 是否为数组、字段名是否与 Go 结构体字段一致(首字母大写) |
| 空响应或连接重置 | 未设置 Content-Type: application/json | 添加 -H "Content-Type: application/json" |
| {"id":null,"result":null,"error":"invalid request"} | JSON 格式错误(如缺少逗号、引号不匹配) | 使用 jq 或在线 JSON 校验工具验证请求体 |
? 进阶建议
- 生产环境务必禁用 Gob RPC:rpc.HandleHTTP() 会暴露 /_goRPC,存在安全风险。仅保留 /_goRPC_ 并通过反向代理限制访问。
- 考虑升级至 gRPC 或 REST:net/rpc/jsonrpc 是遗留方案,无标准错误码、流式支持弱。新项目推荐 gRPC 或 OpenAPI 规范的 REST 接口。
- 调试利器:用 curl -v 查看完整请求/响应头,确认 Content-Type 和状态码;服务端加日志记录 r.Body 可快速定位序列化问题。
掌握 JSON-RPC 协议层的映射规则,是实现 Go RPC 服务多语言互通的核心。只要服务端正确启用 jsonrpc、客户端严格遵循 JSON-RPC 1.0 规范构造请求,即可无缝集成 Python、JavaScript、Java 等任意语言客户端。


















