rpc.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. // Author: NiuJiuRu
  2. // Email: niujiuru@qq.com
  3. package jsonrpc2
  4. import (
  5. "encoding/json"
  6. "errors"
  7. "fmt"
  8. )
  9. type ErrCode int
  10. const (
  11. ErrParse ErrCode = -32700 // 解析错误: "Parse error"
  12. ErrInvalidRequest ErrCode = -32600 // 无效请求: "Invalid request"
  13. ErrMethodNotFound ErrCode = -32601 // 无效方法: "Method not found"
  14. ErrInvalidParams ErrCode = -32602 // 无效参数: "Invalid params"
  15. ErrInternal ErrCode = -32603 // 内部错误: "Internal error"
  16. )
  17. type Error struct {
  18. Code ErrCode `json:"code"` //// 错误码
  19. Message string `json:"message"` //// 错误信息
  20. }
  21. func (e Error) Error() string {
  22. return e.Message
  23. }
  24. type Request struct {
  25. JSONRPC string `json:"jsonrpc"` // 版本号, 固定: "2.0"
  26. Method string `json:"method"` // 调用方法, 执行函数名
  27. Params json.RawMessage `json:"params,omitempty"` // 请求参数, 可选可为空
  28. ID *int `json:"id,omitempty"` // 请求ID, 用于标识请求
  29. }
  30. type Response struct {
  31. JSONRPC string `json:"jsonrpc"` // 版本号, 固定: "2.0"
  32. Result json.RawMessage `json:"result,omitempty"` // 响应结果, 可选可为空
  33. Error *Error `json:"error,omitempty"` // 错误信息, 可选可为空
  34. ID *int `json:"id"` // 应答ID, 响应匹配请求
  35. }
  36. // 解析请求数据
  37. func ParseRequest(input any) (*Request, error) {
  38. var raw []byte
  39. switch v := input.(type) {
  40. case nil:
  41. return nil, errors.New("input is nil")
  42. case string:
  43. raw = []byte(v)
  44. case []byte:
  45. raw = v
  46. default:
  47. return nil, errors.New("unsupported input type: must be string or []byte")
  48. }
  49. var req Request
  50. if err := json.Unmarshal(raw, &req); err != nil {
  51. return nil, fmt.Errorf("unmarshal request: %w", err)
  52. }
  53. return &req, nil
  54. }
  55. // 编码JSON数据
  56. func marshalJSON(input any) (json.RawMessage, error) {
  57. switch v := input.(type) {
  58. case nil:
  59. return nil, nil
  60. case []byte:
  61. return nil, errors.New("[]byte is not allowed: use json.RawMessage for raw JSON")
  62. case json.RawMessage:
  63. return v, nil
  64. default:
  65. b, err := json.Marshal(v)
  66. if err != nil {
  67. return nil, fmt.Errorf("marshal json: %w", err)
  68. }
  69. return json.RawMessage(b), nil
  70. }
  71. }
  72. // 构建一个请求
  73. func BuildRequest(method string, params any, id int) (*Request, error) {
  74. if method == "" {
  75. return nil, errors.New("method must be non-empty")
  76. }
  77. raw, err := marshalJSON(params)
  78. if err != nil {
  79. return nil, err
  80. }
  81. req := &Request{
  82. JSONRPC: "2.0",
  83. Method: method,
  84. ID: &id,
  85. }
  86. if raw != nil { // 非空参数
  87. req.Params = raw
  88. }
  89. return req, nil
  90. }
  91. // 构建一个通知
  92. func BuildNotification(method string, params any) (*Request, error) {
  93. if method == "" {
  94. return nil, errors.New("method must be non-empty")
  95. }
  96. raw, err := marshalJSON(params)
  97. if err != nil {
  98. return nil, err
  99. }
  100. req := &Request{
  101. JSONRPC: "2.0",
  102. Method: method,
  103. }
  104. if raw != nil { // 非空参数
  105. req.Params = raw
  106. }
  107. return req, nil
  108. }
  109. // 构建成功应答
  110. func BuildResult(req *Request, result any) (*Response, error) {
  111. if req.ID == nil { // 通知类型, 不用应答
  112. return nil, nil
  113. }
  114. raw, err := marshalJSON(result)
  115. if err != nil {
  116. return nil, err
  117. }
  118. if raw == nil {
  119. raw = json.RawMessage("null")
  120. }
  121. return &Response{
  122. JSONRPC: "2.0",
  123. Result: raw,
  124. ID: req.ID,
  125. }, nil
  126. }
  127. // 构建错误应答
  128. func BuildError(req *Request, code ErrCode, message string) *Response {
  129. if req.ID == nil { // 通知类型, 不用应答
  130. return nil
  131. }
  132. wmsg := message
  133. switch code {
  134. case ErrParse:
  135. wmsg = "解析错误"
  136. case ErrInvalidRequest:
  137. wmsg = "无效请求"
  138. case ErrMethodNotFound:
  139. wmsg = "无效调用"
  140. case ErrInvalidParams:
  141. wmsg = "无效参数"
  142. case ErrInternal:
  143. wmsg = "内部错误"
  144. }
  145. return &Response{
  146. JSONRPC: "2.0",
  147. Error: &Error{
  148. Code: code,
  149. Message: wmsg,
  150. },
  151. ID: req.ID,
  152. }
  153. }
  154. // 请求转字符串
  155. func (req *Request) String() (string, error) {
  156. b, err := json.Marshal(req)
  157. if err != nil {
  158. return "", fmt.Errorf("marshal request: %w", err)
  159. }
  160. return string(b), nil
  161. }
  162. // 应答转字符串
  163. func (resp *Response) String() (string, error) {
  164. b, err := json.Marshal(resp)
  165. if err != nil {
  166. return "", fmt.Errorf("marshal response: %w", err)
  167. }
  168. return string(b), nil
  169. }