This repository has been archived by the owner on Oct 25, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathjson_rpc.go
142 lines (123 loc) · 3.67 KB
/
json_rpc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package libwimark
import (
"encoding/json"
"errors"
"fmt"
"math/rand"
mqtt "github.com/eclipse/paho.mqtt.golang"
)
const JSON_RPC_VERSION = "2.0"
// clientRequest represents a JSON-RPC request sent by a client.
type JSONRPCClientRequest struct {
// JSON-RPC protocol.
Version string `json:"jsonrpc"`
// A String containing the name of the method to be invoked.
Method string `json:"method"`
// Object to pass as request parameter to the method.
Params interface{} `json:"params,omitempty"`
// The request id. This can be of any type. It is used to match the
// response with the request that it is replying to.
Id int `json:"id,omitempty"`
}
type JSONRPCClientRequestList []JSONRPCClientRequest
// clientResponse represents a JSON-RPC response returned to a client.
type JSONRPCClientResponse struct {
// JSON-RPC protocol.
Version string `json:"jsonrpc"`
Result interface{} `json:"result,omitempty"`
Error *JSONRPC_Error `json:"error,omitempty"`
Id int `json:"id"`
}
type JSONRPCClientResponseList []JSONRPCClientResponse
type JSONRPC_ErrorCode int
type JSONRPC_Error struct {
// code of the error
Code JSONRPC_ErrorCode `json:"code"`
// description of the error
Message string `json:"message"`
// optional data to attach
Data interface{} `json:"data,omitempty"`
}
// RFC error codes
const (
E_PARSE JSONRPC_ErrorCode = -32700
E_INVALID_REQ JSONRPC_ErrorCode = -32600
E_NO_METHOD JSONRPC_ErrorCode = -32601
E_BAD_PARAMS JSONRPC_ErrorCode = -32602
E_INTERNAL JSONRPC_ErrorCode = -32603
E_SERVER JSONRPC_ErrorCode = -32000
)
// EncodeClientRequest encodes parameters for a JSON-RPC client request.
func EncodeRPCRequest(method string, args interface{}) ([]byte, error) {
c := &JSONRPCClientRequest{
Version: JSON_RPC_VERSION,
Method: method,
Params: args,
Id: rand.Int(),
}
return json.Marshal(c)
}
func NewJSONRPCRequest(method string, args interface{}, id int) JSONRPCClientRequest {
return JSONRPCClientRequest{
Version: JSON_RPC_VERSION,
Method: method,
Params: args,
Id: id,
}
}
func MakeRPCError(code JSONRPC_ErrorCode, description string,
id int, data interface{}) *JSONRPCClientResponse {
return &JSONRPCClientResponse{
Id: id,
Version: JSON_RPC_VERSION,
Error: &JSONRPC_Error{
Code: code,
Message: description,
Data: data,
},
}
}
func MakeRPCSuccessResponse(id int, payload interface{}) *JSONRPCClientResponse {
return &JSONRPCClientResponse{
Id: id,
Version: JSON_RPC_VERSION,
Result: payload,
}
}
type JSONRPCProcedure interface {
ProcedureExecute(JSONRPCClientRequest) *JSONRPCClientResponse
}
type RPCServer struct {
// for some reason does not work as below
// RPCs map[TunManagerRPC]Procedure
RPCs map[string]JSONRPCProcedure
}
func (server *RPCServer) ExecuteRPC(req JSONRPCClientRequest) *JSONRPCClientResponse {
p, ok := server.RPCs[req.Method]
if !ok {
err := errors.New("there is no such method")
return MakeRPCError(E_NO_METHOD, err.Error(), req.Id, nil)
}
return p.ProcedureExecute(req)
}
func ProcessJSONRPCMessage(msg mqtt.Message, server *RPCServer) (JSONRPCClientResponseList, error) {
var err error
// get topic in common structure
_, err = ParseRequestTopic(msg.Topic())
if err != nil {
return nil, fmt.Errorf("topic is not supported err := (%s), topic := (%s)",
err.Error(), msg.Topic())
}
var in []JSONRPCClientRequest
// parse incoming rpcs
err = json.Unmarshal(msg.Payload(), &in)
if err != nil {
response := MakeRPCError(E_PARSE, err.Error(), 0, nil)
return JSONRPCClientResponseList{*response}, err
}
rsp := JSONRPCClientResponseList{}
for i := range in {
rsp = append(rsp, *server.ExecuteRPC(in[i]))
}
return rsp, nil
}