2017-12-25 12 views
0

私はゴーLANG RPCリターンEOFエラー

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) 
} 

の下のコードでRPCを呼び出すために、HTTPを使用してい& 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は //インターフェースの応答にクライアント要求のレスポンスボディをデコードします。

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を得ました。

+2

二つの提案が始めるには:1)2)生の要求および応答をログエラーを無視しないでください。 – Marc

答えて

1

この行:

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

を読み取るすべき複数バイトで読者を残し、全体resp.Bodyを読み出します。従ってresp.Body.Readへの連続的な呼び出しはEOFjson.Decoder.Decode方法が返され、所与の読者のコンテンツを復号化するときio.Reader.Read方法を使用し、そう...

そしてresp.Bodyので、サポートしていないインタフェースである、io.ReadCloserあります"巻き戻し"し、ボディコンテンツを複数回(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) 
}