2017-12-25 15 views
0

나는이동 랭 RPC 반환 EOF 오류

// EncodeClientRequest는 JSON-RPC 클라이언트 요청에 대한 매개 변수를 인코딩 EncodeClientRquest & & DecodeClientResponse와

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를 사용하고 있습니다.

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 때문에 ... resp.Body.Read에 대한 연속적인 호출 EOF을 반환하고 주어진 독자의 컨텐츠를 디코딩 할 때 json.Decoder.Decode 방법은 io.Reader.Read 방법을 사용 않으므로 것은 지원하지 않는 인터페이스 인 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) 
}