This commit is contained in:
crusader 2018-04-05 10:12:33 +09:00
parent 8587e2e369
commit 23658adc4b
5 changed files with 33 additions and 68 deletions

View File

@ -2,8 +2,8 @@ package json
import ( import (
"encoding/json" "encoding/json"
"fmt"
crp "git.loafle.net/commons/rpc-go/protocol"
cuej "git.loafle.net/commons/util-go/encoding/json" cuej "git.loafle.net/commons/util-go/encoding/json"
) )
@ -21,7 +21,6 @@ type clientNotification struct {
// ClientNotificationCodec decodes and encodes a single notification. // ClientNotificationCodec decodes and encodes a single notification.
type ClientNotificationCodec struct { type ClientNotificationCodec struct {
noti *clientNotification noti *clientNotification
err error
} }
func (cnc *ClientNotificationCodec) HasResponse() bool { func (cnc *ClientNotificationCodec) HasResponse() bool {
@ -33,36 +32,26 @@ func (cnc *ClientNotificationCodec) Method() string {
} }
func (cnc *ClientNotificationCodec) ReadParams(args []interface{}) error { func (cnc *ClientNotificationCodec) ReadParams(args []interface{}) error {
if cnc.err == nil && cnc.noti.Params != nil { if nil != cnc.noti.Params {
// Note: if scr.request.Params is nil it's not an error, it's an optional member. // Note: if scr.request.Params is nil it's not an error, it's an optional member.
// JSON params structured object. Unmarshal to the args object. // JSON params structured object. Unmarshal to the args object.
if err := cuej.SetValueWithJSONStringArray(*cnc.noti.Params, args); nil != err { if err := cuej.SetValueWithJSONStringArray(*cnc.noti.Params, args); nil != err {
cnc.err = &crp.Error{ return err
Code: crp.E_INVALID_REQ,
Message: err.Error(),
Data: cnc.noti.Params,
}
return cnc.err
} }
return nil return nil
} }
return cnc.err return fmt.Errorf("There is not params")
} }
func (cnc *ClientNotificationCodec) Params() ([]string, error) { func (cnc *ClientNotificationCodec) Params() ([]string, error) {
if cnc.err == nil && cnc.noti.Params != nil { if nil != cnc.noti.Params {
var values []string var values []string
if err := json.Unmarshal(*cnc.noti.Params, &values); err != nil { if err := json.Unmarshal(*cnc.noti.Params, &values); err != nil {
cnc.err = &crp.Error{ return nil, err
Code: crp.E_INVALID_REQ,
Message: err.Error(),
Data: cnc.noti.Params,
}
return nil, cnc.err
} }
return values, nil return values, nil
} }
return nil, cnc.err return nil, fmt.Errorf("There is not params")
} }

View File

@ -14,14 +14,13 @@ import (
type clientResponse struct { type clientResponse struct {
Version string `json:"jsonrpc"` Version string `json:"jsonrpc"`
Result *json.RawMessage `json:"result,omitempty"` Result *json.RawMessage `json:"result,omitempty"`
Error *json.RawMessage `json:"error,omitempty"` Error *protocol.Error `json:"error,omitempty"`
ID interface{} `json:"id,omitempty"` ID interface{} `json:"id,omitempty"`
} }
// ClientResponseCodec decodes and encodes a single request. // ClientResponseCodec decodes and encodes a single request.
type ClientResponseCodec struct { type ClientResponseCodec struct {
res *clientResponse res *clientResponse
err error
} }
func (crc *ClientResponseCodec) ID() interface{} { func (crc *ClientResponseCodec) ID() interface{} {
@ -29,38 +28,22 @@ func (crc *ClientResponseCodec) ID() interface{} {
} }
func (crc *ClientResponseCodec) Result(result interface{}) error { func (crc *ClientResponseCodec) Result(result interface{}) error {
if nil == crc.err && nil != crc.res.Result { if nil == crc.res.Error && nil != crc.res.Result {
if err := json.Unmarshal(*crc.res.Result, result); nil != err { if err := json.Unmarshal(*crc.res.Result, result); nil != err {
crc.err = &protocol.Error{ return err
Code: protocol.E_PARSE,
Message: err.Error(),
Data: crc.res.Result,
}
} }
} }
return crc.err return fmt.Errorf("There is no result")
} }
func (crc *ClientResponseCodec) Error() *protocol.Error { func (crc *ClientResponseCodec) Error() *protocol.Error {
if nil == crc.res.Error { return crc.res.Error
return nil
}
protocolError := &protocol.Error{}
err := json.Unmarshal(*crc.res.Error, protocolError)
if nil != err {
return &protocol.Error{
Code: protocol.E_PARSE,
Message: err.Error(),
Data: crc.res.Error,
}
}
return protocolError
} }
func (crc *ClientResponseCodec) Notification() (protocol.ClientNotificationCodec, error) { func (crc *ClientResponseCodec) Notification() (protocol.ClientNotificationCodec, error) {
if nil != crc.res.ID || nil == crc.res.Result { if nil != crc.res.ID || nil == crc.res.Result {
return nil, fmt.Errorf("RPC[JSON]: This is not notification") return nil, fmt.Errorf("This is not notification")
} }
noti := &clientNotification{} noti := &clientNotification{}
@ -69,7 +52,7 @@ func (crc *ClientResponseCodec) Notification() (protocol.ClientNotificationCodec
return nil, err return nil, err
} }
return &ClientNotificationCodec{noti: noti, err: err}, nil return &ClientNotificationCodec{noti: noti}, nil
} }
// newClientMessageCodec returns a new ClientMessageCodec. // newClientMessageCodec returns a new ClientMessageCodec.
@ -79,19 +62,11 @@ func newClientResponseCodec(buf []byte) (protocol.ClientResponseCodec, error) {
err := json.Unmarshal(buf, res) err := json.Unmarshal(buf, res)
if err != nil { if err != nil {
err = &protocol.Error{ return nil, fmt.Errorf("Cannot unmarshal response [%s] err: %v", string(buf), err)
Code: protocol.E_PARSE,
Message: err.Error(),
Data: res,
}
} }
if res.Version != Version { if res.Version != Version {
err = &protocol.Error{ return nil, fmt.Errorf("The protocol version of response[%s] is not %s", string(buf), Version)
Code: protocol.E_INVALID_REQ,
Message: "jsonrpc must be " + Version,
Data: res,
}
} }
return &ClientResponseCodec{res: res, err: err}, nil return &ClientResponseCodec{res: res}, nil
} }

View File

@ -93,7 +93,7 @@ func (src *ServerRequestCodec) ReadParams(args []interface{}) error {
// JSON params structured object. Unmarshal to the args object. // JSON params structured object. Unmarshal to the args object.
if err := cuej.SetValueWithJSONStringArray(*src.req.Params, args); nil != err { if err := cuej.SetValueWithJSONStringArray(*src.req.Params, args); nil != err {
src.err = &protocol.Error{ src.err = &protocol.Error{
Code: protocol.E_INVALID_REQ, Code: protocol.E_BAD_PARAMS,
Message: err.Error(), Message: err.Error(),
Data: src.req.Params, Data: src.req.Params,
} }
@ -110,7 +110,7 @@ func (src *ServerRequestCodec) Params() ([]string, error) {
if err := json.Unmarshal(*src.req.Params, &values); err != nil { if err := json.Unmarshal(*src.req.Params, &values); err != nil {
src.err = &protocol.Error{ src.err = &protocol.Error{
Code: protocol.E_INVALID_REQ, Code: protocol.E_BAD_PARAMS,
Message: err.Error(), Message: err.Error(),
Data: src.req.Params, Data: src.req.Params,
} }
@ -122,21 +122,23 @@ func (src *ServerRequestCodec) Params() ([]string, error) {
return nil, src.err return nil, src.err
} }
func (src *ServerRequestCodec) NewResponse(reply interface{}) ([]byte, error) { func (src *ServerRequestCodec) NewResponse(reply interface{}, err error) ([]byte, error) {
res := &serverResponse{Version: Version, Result: reply, ID: src.req.ID} res := &serverResponse{Version: Version, Result: reply, ID: src.req.ID}
return src.newServerResponse(res)
} if nil != err {
func (src *ServerRequestCodec) NewError(status int, err error) ([]byte, error) { jsonErr, ok := err.(*protocol.Error)
jsonErr, ok := err.(*protocol.Error) if !ok {
if !ok { jsonErr = &protocol.Error{
jsonErr = &protocol.Error{ Code: protocol.E_SERVER,
Code: protocol.E_SERVER, Message: err.Error(),
Message: err.Error(), }
} }
res.Error = jsonErr
} }
res := &serverResponse{Version: Version, Error: jsonErr, ID: src.req.ID}
return src.newServerResponse(res) return src.newServerResponse(res)
} }
func (src *ServerRequestCodec) newServerResponse(res *serverResponse) ([]byte, error) { func (src *ServerRequestCodec) newServerResponse(res *serverResponse) ([]byte, error) {
return json.Marshal(res) return json.Marshal(res)

View File

@ -11,6 +11,5 @@ type ServerCodec interface {
type ServerRequestCodec interface { type ServerRequestCodec interface {
RegistryCodec RegistryCodec
NewResponse(reply interface{}) ([]byte, error) NewResponse(reply interface{}, err error) ([]byte, error)
NewError(status int, err error) ([]byte, error)
} }

View File

@ -65,7 +65,7 @@ func (rr *rpcRegistry) HasMethod(method string) bool {
// excluding the charset definition. // excluding the charset definition.
func (rr *rpcRegistry) Invoke(codec protocol.RegistryCodec) (result interface{}, err error) { func (rr *rpcRegistry) Invoke(codec protocol.RegistryCodec) (result interface{}, err error) {
serviceSpec, methodSpec, errGet := rr.services.get(codec.Method()) serviceSpec, methodSpec, errGet := rr.services.get(codec.Method())
if errGet != nil { if nil != errGet {
return nil, errGet return nil, errGet
} }
// Decode the args. // Decode the args.