mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 14:52:17 +00:00
RPCResponse.Result is json.RawMessage
This commit is contained in:
parent
0bcae125c2
commit
aff561d8c3
@ -2,6 +2,7 @@ package rpcclient
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@ -22,8 +23,8 @@ func NewClientJSONRPC(remote string) *ClientJSONRPC {
|
||||
return &ClientJSONRPC{remote}
|
||||
}
|
||||
|
||||
func (c *ClientJSONRPC) Call(method string, params []interface{}) (interface{}, error) {
|
||||
return CallHTTP_JSONRPC(c.remote, method, params)
|
||||
func (c *ClientJSONRPC) Call(method string, params []interface{}, result interface{}) (interface{}, error) {
|
||||
return CallHTTP_JSONRPC(c.remote, method, params, result)
|
||||
}
|
||||
|
||||
// URI takes params as a map
|
||||
@ -38,11 +39,11 @@ func NewClientURI(remote string) *ClientURI {
|
||||
return &ClientURI{remote}
|
||||
}
|
||||
|
||||
func (c *ClientURI) Call(method string, params map[string]interface{}) (interface{}, error) {
|
||||
return CallHTTP_URI(c.remote, method, params)
|
||||
func (c *ClientURI) Call(method string, params map[string]interface{}, result interface{}) (interface{}, error) {
|
||||
return CallHTTP_URI(c.remote, method, params, result)
|
||||
}
|
||||
|
||||
func CallHTTP_JSONRPC(remote string, method string, params []interface{}) (interface{}, error) {
|
||||
func CallHTTP_JSONRPC(remote string, method string, params []interface{}, result interface{}) (interface{}, error) {
|
||||
// Make request and get responseBytes
|
||||
request := rpctypes.RPCRequest{
|
||||
JSONRPC: "2.0",
|
||||
@ -63,10 +64,10 @@ func CallHTTP_JSONRPC(remote string, method string, params []interface{}) (inter
|
||||
return nil, err
|
||||
}
|
||||
log.Info(Fmt("RPC response: %v", string(responseBytes)))
|
||||
return unmarshalResponseBytes(responseBytes)
|
||||
return unmarshalResponseBytes(responseBytes, result)
|
||||
}
|
||||
|
||||
func CallHTTP_URI(remote string, method string, params map[string]interface{}) (interface{}, error) {
|
||||
func CallHTTP_URI(remote string, method string, params map[string]interface{}, result interface{}) (interface{}, error) {
|
||||
values, err := argsToURLValues(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -81,18 +82,18 @@ func CallHTTP_URI(remote string, method string, params map[string]interface{}) (
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return unmarshalResponseBytes(responseBytes)
|
||||
return unmarshalResponseBytes(responseBytes, result)
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
func unmarshalResponseBytes(responseBytes []byte) (interface{}, error) {
|
||||
func unmarshalResponseBytes(responseBytes []byte, result interface{}) (interface{}, error) {
|
||||
// read response
|
||||
// if rpc/core/types is imported, the result will unmarshal
|
||||
// into the correct type
|
||||
var err error
|
||||
response := &rpctypes.RPCResponse{}
|
||||
wire.ReadJSON(response, responseBytes, &err)
|
||||
err = json.Unmarshal(responseBytes, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -100,7 +101,9 @@ func unmarshalResponseBytes(responseBytes []byte) (interface{}, error) {
|
||||
if errorStr != "" {
|
||||
return nil, errors.New(errorStr)
|
||||
}
|
||||
return response.Result, err
|
||||
// unmarshal the RawMessage into the result
|
||||
result = wire.ReadJSONPtr(result, *response.Result, &err)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func argsToURLValues(args map[string]interface{}) (url.Values, error) {
|
||||
|
@ -1,13 +1,13 @@
|
||||
package rpcclient
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/go-rpc/types"
|
||||
"github.com/tendermint/go-wire"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -79,7 +79,7 @@ func (wsc *WSClient) receiveEventsRoutine() {
|
||||
break
|
||||
} else {
|
||||
var response rpctypes.RPCResponse
|
||||
wire.ReadJSON(&response, data, &err)
|
||||
err := json.Unmarshal(data, &response)
|
||||
if err != nil {
|
||||
log.Info("WSClient failed to parse message", "error", err, "data", string(data))
|
||||
wsc.Stop()
|
||||
|
@ -19,6 +19,8 @@ import (
|
||||
"github.com/tendermint/go-wire"
|
||||
)
|
||||
|
||||
// Adds a route for each function in the funcMap, as well as general jsonrpc and websocket handlers for all functions.
|
||||
// "result" is the interface on which the result objects are registered, and is popualted with every RPCResponse
|
||||
func RegisterRPCFuncs(mux *http.ServeMux, funcMap map[string]*RPCFunc) {
|
||||
// HTTP endpoints
|
||||
for funcName, rpcFunc := range funcMap {
|
||||
@ -433,7 +435,6 @@ func (wsc *wsConnection) readRoutine() {
|
||||
// receives on a write channel and writes out on the socket
|
||||
func (wsc *wsConnection) writeRoutine() {
|
||||
defer wsc.baseConn.Close()
|
||||
var n, err = int(0), error(nil)
|
||||
for {
|
||||
select {
|
||||
case <-wsc.Quit:
|
||||
@ -446,14 +447,12 @@ func (wsc *wsConnection) writeRoutine() {
|
||||
return
|
||||
}
|
||||
case msg := <-wsc.writeChan:
|
||||
buf := new(bytes.Buffer)
|
||||
wire.WriteJSON(msg, buf, &n, &err)
|
||||
jsonBytes, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
log.Error("Failed to marshal RPCResponse to JSON", "error", err)
|
||||
} else {
|
||||
wsc.baseConn.SetWriteDeadline(time.Now().Add(time.Second * wsWriteTimeoutSeconds))
|
||||
bufBytes := buf.Bytes()
|
||||
if err = wsc.baseConn.WriteMessage(websocket.TextMessage, bufBytes); err != nil {
|
||||
if err = wsc.baseConn.WriteMessage(websocket.TextMessage, jsonBytes); err != nil {
|
||||
log.Warn("Failed to write response on websocket", "error", err)
|
||||
wsc.Stop()
|
||||
return
|
||||
@ -507,13 +506,18 @@ func (wm *WebsocketManager) WebsocketHandler(w http.ResponseWriter, r *http.Requ
|
||||
// rpc.websocket
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// returns is result struct and error. If error is not nil, return it
|
||||
// NOTE: assume returns is result struct and error. If error is not nil, return it
|
||||
func unreflectResult(returns []reflect.Value) (interface{}, error) {
|
||||
errV := returns[1]
|
||||
if errV.Interface() != nil {
|
||||
return nil, fmt.Errorf("%v", errV.Interface())
|
||||
}
|
||||
return returns[0].Interface(), nil
|
||||
rv := returns[0]
|
||||
// the result is a registered interface,
|
||||
// we need a pointer to it so we can marshal with type byte
|
||||
rvp := reflect.New(rv.Type())
|
||||
rvp.Elem().Set(rv)
|
||||
return rvp.Interface(), nil
|
||||
}
|
||||
|
||||
// writes a list of available rpc endpoints as an html page
|
||||
|
@ -3,6 +3,7 @@ package rpcserver
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
@ -12,7 +13,7 @@ import (
|
||||
"github.com/tendermint/go-alert"
|
||||
. "github.com/tendermint/go-common"
|
||||
. "github.com/tendermint/go-rpc/types"
|
||||
"github.com/tendermint/go-wire"
|
||||
//"github.com/tendermint/go-wire"
|
||||
)
|
||||
|
||||
func StartHTTPServer(listenAddr string, handler http.Handler) (net.Listener, error) {
|
||||
@ -32,7 +33,11 @@ func StartHTTPServer(listenAddr string, handler http.Handler) (net.Listener, err
|
||||
}
|
||||
|
||||
func WriteRPCResponseHTTP(w http.ResponseWriter, res RPCResponse) {
|
||||
jsonBytes := wire.JSONBytesPretty(res)
|
||||
// jsonBytes := wire.JSONBytesPretty(res)
|
||||
jsonBytes, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(200)
|
||||
w.Write(jsonBytes)
|
||||
|
@ -1,7 +1,10 @@
|
||||
package rpctypes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/tendermint/go-events"
|
||||
"github.com/tendermint/go-wire"
|
||||
)
|
||||
|
||||
type RPCRequest struct {
|
||||
@ -39,17 +42,18 @@ type Result interface {
|
||||
//----------------------------------------
|
||||
|
||||
type RPCResponse struct {
|
||||
JSONRPC string `json:"jsonrpc"`
|
||||
ID string `json:"id"`
|
||||
Result Result `json:"result"`
|
||||
Error string `json:"error"`
|
||||
JSONRPC string `json:"jsonrpc"`
|
||||
ID string `json:"id"`
|
||||
Result *json.RawMessage `json:"result"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
func NewRPCResponse(id string, res Result, err string) RPCResponse {
|
||||
func NewRPCResponse(id string, res interface{}, err string) RPCResponse {
|
||||
raw := json.RawMessage(wire.JSONBytes(res))
|
||||
return RPCResponse{
|
||||
JSONRPC: "2.0",
|
||||
ID: id,
|
||||
Result: res,
|
||||
Result: &raw,
|
||||
Error: err,
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user