json2.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. package jsonrpc
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "time"
  6. "github.com/levigross/grequests"
  7. "github.com/pkg/errors"
  8. )
  9. type ErrorCode int
  10. const (
  11. E_PARSE ErrorCode = -32700
  12. E_INVALID_REQ ErrorCode = -32600
  13. E_NO_METHOD ErrorCode = -32601
  14. E_BAD_PARAMS ErrorCode = -32602
  15. E_INTERNAL ErrorCode = -32603
  16. E_SERVER ErrorCode = -32000
  17. )
  18. const JSONRPC_VERSION = "2.0"
  19. type Request struct {
  20. Version string `json:"jsonrpc"`
  21. ID int64 `json:"id"`
  22. Method string `json:"method"`
  23. Params interface{} `json:"params,omitempty"`
  24. }
  25. type Response struct {
  26. Version string `json:"jsonrpc"`
  27. ID int64 `json:"id"`
  28. Result *json.RawMessage `json:"result,omitempty"`
  29. Error *json.RawMessage `json:"error,omitempty"`
  30. }
  31. type RPCError struct {
  32. Code ErrorCode `json:"code"`
  33. Message string `json:"message"`
  34. Data interface{} `json:"data,omitempty"`
  35. }
  36. func (re *RPCError) Error() string {
  37. return fmt.Sprintf("code:%d message:%s data:%v", re.Code, re.Message, re.Data)
  38. }
  39. func NewRequest(method string, params ...interface{}) *Request {
  40. return &Request{
  41. Version: JSONRPC_VERSION,
  42. ID: time.Now().Unix(),
  43. Method: method,
  44. Params: params,
  45. }
  46. }
  47. type Client struct {
  48. URL string
  49. Timeout time.Duration
  50. ErrorCallback func() error
  51. ErrorFixTimeout time.Duration
  52. ServerOK func() bool
  53. }
  54. func NewClient(url string) *Client {
  55. return &Client{
  56. URL: url,
  57. Timeout: 60 * time.Second,
  58. }
  59. }
  60. func (r *Client) Call(method string, params ...interface{}) (resp *Response, err error) {
  61. // timeout maybe no needed
  62. gres, err := grequests.Post(r.URL, &grequests.RequestOptions{
  63. RequestTimeout: r.Timeout,
  64. JSON: NewRequest(method, params...),
  65. })
  66. if err != nil {
  67. return
  68. }
  69. if gres.Error != nil {
  70. err = gres.Error
  71. return
  72. }
  73. resp = new(Response)
  74. if err = gres.JSON(resp); err != nil {
  75. return
  76. }
  77. if resp.Error != nil {
  78. rpcErr := &RPCError{}
  79. if er := json.Unmarshal(*resp.Error, rpcErr); er != nil {
  80. err = &RPCError{
  81. Code: E_SERVER,
  82. Message: string(*resp.Error),
  83. }
  84. return
  85. }
  86. err = rpcErr
  87. }
  88. return
  89. }
  90. func (r *Client) RobustCall(method string, params ...interface{}) (resp *Response, err error) {
  91. resp, err = r.Call(method, params...)
  92. if err == nil {
  93. return
  94. }
  95. if r.ErrorCallback == nil || r.ErrorCallback() != nil {
  96. return
  97. }
  98. start := time.Now()
  99. for {
  100. if time.Now().Sub(start) > r.ErrorFixTimeout {
  101. return
  102. }
  103. if r.ServerOK != nil && !r.ServerOK() {
  104. err = errors.New("jsonrpc server is down, auto-recover failed")
  105. return
  106. }
  107. time.Sleep(1 * time.Second)
  108. resp, err = r.Call(method, params...)
  109. if err == nil {
  110. return
  111. }
  112. }
  113. }