2

我很新。

我使用这个包https://github.com/kdar/httprpc来做我的 json-rpc v 1.0 请求(因为 golang 只实现 2.0)

我有一个问题,我正在调用的这个服务器将“id”作为字符串返回,比如

"id":"345"

代替

"id":345

我发现的唯一方法是使用字符串而不是 uint64 重新定义 clientResponse

type clientResponse struct {
    Result *json.RawMessage `json:"result"`
    Error  interface{}      `json:"error"`
    Id     string           `json:"id"`
}

并重新定义完全相同的 DecodeClientResponse 函数以使用我的 clientResponse

而不是 CallJson,我调用(DecodeClientResponse 而不是 gjson.DecodeClientResponse):

httprpc.CallRaw(address, method, &params, &reply, "application/json",
            gjson.EncodeClientRequest, DecodeClientResponse)

我觉得这很丑陋,有什么办法可以做得更好吗?

谢谢

4

2 回答 2

2

json-rpc v 1.0 指定:

id - 请求 ID。这可以是任何类型。它用于将响应与它正在回复的请求相匹配。

也就是说,id可以是任何东西(甚至是数组),并且服务器响应应该包含相同的 id 值和类型,在您的情况下它不会这样做。因此,您与之通信的服务器没有正确完成其工作,并且没有遵循 json-rpc v 1.0 规范。

所以,是的,你需要做“丑陋”的解决方案,并为这个“坏掉的”服务器创建一个新的解码器功能。Jeremy Wall 的建议有效(但int应该改为uint64),至少应该让你避免使用stringas 类型。

编辑

我对httprpc包裹的了解不够,无法知道它如何处理Id价值。但是,如果您想要字符串或 int,您应该能够将 Id 设置clientResponse为:

Id interface{} `json:"id"`

检查值时Id使用类型开关:

var id int
// response is of type clientResponse
switch t := response.Id.(type) {
default:
    // Error. Bad type
case string:
    var err error
    id, err = strconv.Atoi(t)
    if err != nil {
        // Error. Not possible to convert string to int
    }
case int:
    id = t
}
// id now contains your value
于 2013-03-31T19:23:33.033 回答
1

尝试

type clientResponse struct {
    Result *json.RawMessage `json:"result"`
    Error  interface{}      `json:"error"`

    # Tell encoding/json that the field is
    # encoded as a json string even though the type is int.
    Id     int           `json:"id,string"`
}

只要库在后台使用 encoding/json,这应该可以工作。

于 2013-03-30T04:20:58.957 回答