XRPLF / rippled

Decentralized cryptocurrency blockchain daemon implementing the XRP Ledger protocol in C++
https://xrpl.org
ISC License
4.52k stars 1.47k forks source link

Is rippled release the rpc connect resource? The service is unavailable. #2900

Open qiluge opened 5 years ago

qiluge commented 5 years ago

I have deployed a ripple sync node, and monitor its' height and parse the latest closed ledger by rpc method ledger_closed and ledger. Usually I have lost my connection, because the rippled server return connection error, such as connect reset by peer, EOF and conenct refuse. And sometime rippled give the result while call ledger_closed rpc method, but the result cannot be parsed by json, the unmarshal error is invalid character 'S' looking for beginning of value

qiluge commented 5 years ago

and my monitor program run with rippled sync node at same machine.

qiluge commented 5 years ago

the original response of server is Service Unavailable of error invalid character 'S' looking for beginning of value

MarkusTeufelberger commented 5 years ago

Could you give an example of how your monitoring program calls the server e.g. via curl?

qiluge commented 5 years ago

func GetHeight(restClient *utils.RestClient, url string) (uint32, error) {
    req := &rpcReq{
        Method: "ledger_closed",
    }
    reqData, err := json.Marshal(req)
    if err != nil {
        return 0, fmt.Errorf("GetHeight: marshal req err: %s", err)
    }
    respData, err := restClient.SendRestRequest(url, reqData)
    if err != nil {
        return 0, fmt.Errorf("GetHeight: send req err: %s", err)
    }
    resp := &heightResp{}
    err = json.Unmarshal(respData, resp)
    if err != nil {
        return 0, fmt.Errorf("GetHeight, unmarshal resp err: %s, origin resp is %s", err, string(respData))
    }
    if resp.Result.Status != "success" {
        return 0, fmt.Errorf("GetHeight, resp failed, status: %s", resp.Result.Status)
    }
    return resp.Result.LedgerIndex, nil
}
func (self *RestClient) SendRestRequest(addr string, data []byte) ([]byte, error) {
    resp, err := self.restClient.Post(addr, "application/json", strings.NewReader(string(data)))
    if err != nil {
        return nil, fmt.Errorf("http post request:%s error:%s", data, err)
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return nil, fmt.Errorf("read rest response body error:%s", err)
    }
    return body, nil
}

call getHeight method per second.

qiluge commented 5 years ago

and all rpc request is sent by restClient, the code is generated rest client.

func NewRestClient() *RestClient {
    return &RestClient{
        restClient: &http.Client{
            Transport: &http.Transport{
                MaxIdleConnsPerHost:   5,
                DisableKeepAlives:     false,
                IdleConnTimeout:       time.Second * 300,
                ResponseHeaderTimeout: time.Second * 300,
                TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
            },
            Timeout: time.Second * 300,
        },
    }
}
yxxyun commented 5 years ago

why not use "subscribe" https://developers.ripple.com/subscribe.html

qiluge commented 5 years ago

Because reconnection is a little troublesome.

qiluge commented 5 years ago

image

and there are some new error info

carlhua commented 4 years ago

Servers sometimes disconnect, does your script handle all the error cases? If there is an issue with the error messages returned by rippled, please kindly let us know.