golang实现JSON-RPC 2.0 HTTP客户端通信插件库jsonrpc的使用
Golang 实现 JSON-RPC 2.0 HTTP 客户端通信插件库 jsonrpc 的使用
简介
这是一个基于 JSON-RPC 2.0 规范的 Golang 实现,通过 HTTP 协议进行 RPC 通信的客户端库。
安装
go get -u github.com/ybbus/jsonrpc/v3
快速开始
以下是一个简单的示例,展示如何获取和更新人员信息:
package main
import (
"context"
"github.com/ybbus/jsonrpc/v3"
)
type Person struct {
ID int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
rpcClient := jsonrpc.NewClient("http://my-rpc-service:8080/rpc")
var person *Person
rpcClient.CallFor(context.Background(), &person, "getPersonById", 4711)
person.Age = 33
rpcClient.Call(context.Background(), "updatePerson", person)
}
详细使用
生成 JSON-RPC 请求
简单调用:
func main() {
rpcClient := jsonrpc.NewClient("http://my-rpc-service:8080/rpc")
rpcClient.Call(ctx, "getDate")
// 生成请求体: {"method":"getDate","id":0,"jsonrpc":"2.0"}
}
带参数的调用:
func main() {
rpcClient := jsonrpc.NewClient("http://my-rpc-service:8080/rpc")
rpcClient.Call(ctx, "addNumbers", 1, 2)
// 生成请求体: {"method":"addNumbers","params":[1,2],"id":0,"jsonrpc":"2.0"}
}
处理 JSON-RPC 响应
基本错误处理:
func main() {
rpcClient := jsonrpc.NewClient("http://my-rpc-service:8080/rpc")
response, err := rpcClient.Call(ctx, "addNumbers", 1, 2)
if err != nil {
// 处理网络/HTTP错误
}
if response.Error != nil {
// 处理RPC错误
// 检查 response.Error.Code, response.Error.Message 和可选的 response.Error.Data
}
}
获取响应结果:
func main() {
rpcClient := jsonrpc.NewClient("http://my-rpc-service:8080/rpc")
response, _ := rpcClient.Call(ctx, "addNumbers", 1, 2)
result, err := response.GetInt()
if err != nil {
// 结果无法解析为整数
}
// 其他基本类型获取方法:
response.GetFloat()
response.GetString()
response.GetBool()
}
使用 CallFor() 便捷方法
type Person struct {
Id int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
rpcClient := jsonrpc.NewClient("http://my-rpc-service:8080/rpc")
var person *Person
err := rpcClient.CallFor(ctx, &person, "getPersonById", 123)
if err != nil || person == nil {
// 处理错误
}
fmt.Println(person.Name)
}
使用批量请求
func main() {
rpcClient := jsonrpc.NewClient("http://my-rpc-service:8080/rpc")
response, _ := rpcClient.CallBatch(ctx, RPCRequests{
NewRequest("myMethod1", 1, 2, 3),
NewRequest("anotherMethod", "Alex", 35, true),
NewRequest("myMethod2", &Person{
Name: "Emmy",
Age: 4,
}),
})
}
自定义 HTTP 客户端
func main() {
proxyURL, _ := url.Parse("http://proxy:8080")
transport := &http.Transport{Proxy: http.ProxyURL(proxyURL)}
httpClient := &http.Client{
Transport: transport,
}
rpcClient := jsonrpc.NewClientWithOpts("http://my-rpc-service:8080/rpc", &jsonrpc.RPCClientOpts{
HTTPClient: httpClient,
})
// 请求现在会使用代理
}
基本认证
func main() {
rpcClient := jsonrpc.NewClientWithOpts("http://my-rpc-service:8080/rpc", &jsonrpc.RPCClientOpts{
CustomHeaders: map[string]string{
"Authorization": "Basic " + base64.StdEncoding.EncodeToString([]byte("myUser"+":"+"mySecret")),
},
})
response, _ := rpcClient.Call(ctx, "addNumbers", 1, 2) // 发送带 Authorization 头的请求
}
OAuth 认证
func main() {
credentials := clientcredentials.Config{
ClientID: "myID",
ClientSecret: "mySecret",
TokenURL: "http://mytokenurl",
}
rpcClient := jsonrpc.NewClientWithOpts("http://my-rpc-service:8080/rpc", &jsonrpc.RPCClientOpts{
HTTPClient: credentials.Client(context.Background()),
})
// 请求现在会获取并使用 OAuth token
}
高级配置
允许响应中的未知字段
func main() {
rpcClient := jsonrpc.NewClientWithOpts("http://my-rpc-service:8080/rpc", &jsonrpc.RPCClientOpts{
AllowUnknownFields: true,
})
// 现在响应中允许未知字段
}
修改默认请求 ID
func main() {
rpcClient := jsonrpc.NewClientWithOpts("http://my-rpc-service:8080/rpc", &jsonrpc.RPCClientOpts{
DefaultRequestID: 1,
})
// 请求现在默认 ID 为 1
}
以上是 jsonrpc 库的基本使用方法和示例代码。这个库提供了灵活的配置选项,可以满足各种 JSON-RPC 2.0 客户端通信需求。
更多关于golang实现JSON-RPC 2.0 HTTP客户端通信插件库jsonrpc的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang实现JSON-RPC 2.0 HTTP客户端通信插件库jsonrpc的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang实现JSON-RPC 2.0 HTTP客户端通信
JSON-RPC 2.0是一种轻量级的远程过程调用协议,使用JSON作为数据格式。在Golang中,我们可以使用标准库net/rpc/jsonrpc
来实现JSON-RPC客户端通信。
基本使用
1. 标准库实现
Golang标准库提供了net/rpc/jsonrpc
包,但它是基于TCP连接的。对于HTTP通信,我们需要稍作封装:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type Request struct {
Jsonrpc string `json:"jsonrpc"`
Method string `json:"method"`
Params []interface{} `json:"params"`
ID int `json:"id"`
}
type Response struct {
Jsonrpc string `json:"jsonrpc"`
Result interface{} `json:"result,omitempty"`
Error *RpcError `json:"error,omitempty"`
ID int `json:"id"`
}
type RpcError struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}
func Call(url string, method string, params []interface{}) (*Response, error) {
request := Request{
Jsonrpc: "2.0",
Method: method,
Params: params,
ID: 1,
}
payload, err := json.Marshal(request)
if err != nil {
return nil, err
}
resp, err := http.Post(url, "application/json", bytes.NewBuffer(payload))
if err != nil {
return nil, err
}
defer resp.Body.Close()
var response Response
err = json.NewDecoder(resp.Body).Decode(&response)
if err != nil {
return nil, err
}
if response.Error != nil {
return nil, fmt.Errorf("RPC error: %v (code: %d)", response.Error.Message, response.Error.Code)
}
return &response, nil
}
func main() {
response, err := Call("http://example.com/rpc", "add", []interface{}{1, 2})
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Result: %v\n", response.Result)
}
2. 使用第三方库
更推荐使用成熟的第三方库如github.com/ybbus/jsonrpc
,它提供了更完善的HTTP JSON-RPC 2.0客户端实现:
package main
import (
"fmt"
"github.com/ybbus/jsonrpc/v2"
)
func main() {
// 创建RPC客户端
rpcClient := jsonrpc.NewClient("http://example.com/rpc")
// 同步调用
response, err := rpcClient.Call("add", 1, 2)
if err != nil {
fmt.Println("Error:", err)
return
}
// 处理响应
var result int
err = response.GetObject(&result)
if err != nil {
fmt.Println("Error parsing result:", err)
return
}
fmt.Printf("Result: %d\n", result)
// 异步调用
asyncCall := rpcClient.Go("add", []int{3, 4}, nil)
select {
case reply := <-asyncCall.Done:
if reply.Error != nil {
fmt.Println("Async error:", reply.Error)
return
}
var asyncResult int
reply.GetObject(&asyncResult)
fmt.Printf("Async result: %d\n", asyncResult)
}
}
高级功能
1. 自定义HTTP客户端
rpcClient := jsonrpc.NewClientWithOpts("http://example.com/rpc", &jsonrpc.RPCClientOpts{
HTTPClient: &http.Client{
Timeout: 30 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 10,
IdleConnTimeout: 30 * time.Second,
DisableCompression: true,
},
},
CustomHeaders: map[string]string{
"X-Custom-Header": "value",
},
})
2. 批量请求
batch := []jsonrpc.RPCRequest{
{
Method: "add",
Params: []int{1, 2},
},
{
Method: "subtract",
Params: []int{5, 3},
},
}
responses, err := rpcClient.CallBatch(batch)
if err != nil {
fmt.Println("Batch error:", err)
return
}
for _, response := range responses {
var result int
response.GetObject(&result)
fmt.Printf("Method %s result: %d\n", response.RPCRequest.Method, result)
}
3. 错误处理
response, err := rpcClient.Call("divide", 10, 0)
if err != nil {
if rpcErr, ok := err.(*jsonrpc.RPCError); ok {
fmt.Printf("RPC error (code %d): %s\n", rpcErr.Code, rpcErr.Message)
} else {
fmt.Println("Network/other error:", err)
}
return
}
最佳实践
- 连接池管理:重用HTTP客户端以减少连接开销
- 超时设置:为RPC调用设置合理的超时时间
- 错误重试:实现简单的重试机制处理暂时性错误
- 日志记录:记录请求和响应以便调试
- 指标监控:跟踪RPC调用的延迟和成功率
总结
Golang中实现JSON-RPC 2.0 HTTP客户端通信有多种方式,从简单的标准库封装到使用功能丰富的第三方库。github.com/ybbus/jsonrpc
库提供了最完整的实现,包括批量请求、异步调用等高级功能,是大多数场景下的最佳选择。
对于简单的需求,标准库封装可能足够;但对于生产环境,建议使用成熟的第三方库以获得更好的稳定性、性能和功能支持。