Golang GRPC 返回 EOF 错误

标签 go json-rpc

我正在使用 http 通过以下代码调用 RPC

func (c *CallClient) Wallet(method string, req, rep interface{}) error {
    client := &http.Client{}
    data, _ :=  EncodeClientRequest(method, req)
    reqest, _ := http.NewRequest("POST", c.endpoint, bytes.NewBuffer(data))
    resp, err := client.Do(reqest)
    if err != nil {
        return err
    }
    defer resp.Body.Close()
    io.Copy(ioutil.Discard, resp.Body)
    return DecodeClientResponse(resp.Body, rep)
}

使用 EncodeClientRquest && DecodeClientResponse

//EncodeClientRequest 为 JSON-RPC 客户端请求编码参数。

func EncodeClientRequest(method string, args interface{}) ([]byte, error) {
    c := &clientRequest{
        Version: "2.0",
        Method: method,
        Params: [1]interface{}{args},
        Id:     uint64(rand.Int63()),
    }

    return json.Marshal(c)
}

//DecodeClientResponse 将客户端请求的响应体解码为 //接口(interface)回复。

func DecodeClientResponse(r io.Reader, reply interface{}) error {
    var c clientResponse
    if err := json.NewDecoder(r).Decode(&c); err != nil {
        return err
    }
    if c.Error != nil {
        return fmt.Errorf("%v", c.Error)
    }
    if c.Result == nil {
        return errors.New("result is null")
    }
    return json.Unmarshal(*c.Result, reply)
}

我收到错误 EOF。

最佳答案

这一行:

io.Copy(ioutil.Discard, resp.Body)

读取整个 resp.Body,让读取器没有更多的字节要读取。因此,对 resp.Body.Read 的任何连续调用都将返回 EOF 并且 json.Decoder.Decode 方法确实使用了 io。 Reader.Read 解码给定阅读器内容时的方法,所以...

而且由于resp.Body是一个io.ReadCloser,它是一个不支持“倒带”的接口(interface),你想要阅读正文内容超过一次(ioutil.Discard 和 json.Decode),您必须将正文读入一个变量,之后您可以重新读取该变量。这取决于你如何做到这一点,一片字节,或 bytes.Reader,或其他东西。

使用 bytes.Reader 的例子:

func (c *CallClient) Wallet(method string, req, rep interface{}) error {
    client := &http.Client{}
    data, err := EncodeClientRequest(method, req)
    if err != nil {
        return err
    }
    reqest, err := http.NewRequest("POST", c.endpoint, bytes.NewBuffer(data))
    if err != nil {
        return err
    }
    resp, err := client.Do(reqest)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    // get a reader that can be "rewound"
    buf := bytes.NewBuffer(nil)
    if _, err := io.Copy(buf, resp.Body); err != nil {
        return err
    }
    br := bytes.NewReader(buf.Bytes())

    if _, err := io.Copy(ioutil.Discard, br); err != nil {
        return err
    }

    // rewind
    if _, err := br.Seek(0, 0); err != nil {
        return err
    }
    return DecodeClientResponse(br, rep)
}

关于Golang GRPC 返回 EOF 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47970463/

相关文章:

java - 在java中实现具有双向支持的jsonrpc 2.0的最佳库

pointers - 为什么指针上的方法在指针是变量时起作用,而在其他情况下不起作用?

go - 是在赋值给结构原子吗?

go - 存储和检索接口(interface)的字节表示

go - 在 Golang 的同一台服务器上调用已注册的 RPC 方法

java - 如何处理 Java HTTP Server 上不匹配/不需要的或有效的请求?

go - 在 net/http golang 中链接中间件

go - 为什么我的代码在不关闭 channel 的情况下处于死锁状态?

c++ - C++中json-rpc的速度

android - android-json-rpc 库的工作线程示例