ing
This commit is contained in:
parent
efea9e8ca6
commit
96d9105d30
|
@ -5,7 +5,7 @@ import "git.loafle.net/commons_go/rpc/protocol"
|
|||
type ClientReadWriteCloseHandler interface {
|
||||
Connect(clientCTX ClientContext) (interface{}, error)
|
||||
ReadResponse(clientCTX ClientContext, codec protocol.ClientCodec, conn interface{}) (protocol.ClientResponseCodec, error)
|
||||
WriteRequest(clientCTX ClientContext, codec protocol.ClientCodec, conn interface{}, method string, params interface{}, id interface{}) error
|
||||
WriteRequest(clientCTX ClientContext, codec protocol.ClientCodec, conn interface{}, method string, params []interface{}, id interface{}) error
|
||||
Disconnect(clientCTX ClientContext, conn interface{})
|
||||
|
||||
Validate()
|
||||
|
|
|
@ -17,7 +17,7 @@ func (crwch *ClientReadWriteCloseHandlers) ReadResponse(clientCTX ClientContext,
|
|||
return nil, fmt.Errorf("RPC Client RWC Handler: ClientHandlers method[ReadResponse] is not implement")
|
||||
}
|
||||
|
||||
func (crwch *ClientReadWriteCloseHandlers) WriteRequest(clientCTX ClientContext, codec protocol.ClientCodec, conn interface{}, method string, params interface{}, id interface{}) error {
|
||||
func (crwch *ClientReadWriteCloseHandlers) WriteRequest(clientCTX ClientContext, codec protocol.ClientCodec, conn interface{}, method string, params []interface{}, id interface{}) error {
|
||||
return fmt.Errorf("RPC Client RWC Handler: ClientHandlers method[WriteRequest] is not implement")
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ func (crwch *ClientReadWriteCloseHandlers) ReadResponse(clientCTX client.ClientC
|
|||
return resCodec, err
|
||||
}
|
||||
|
||||
func (crwch *ClientReadWriteCloseHandlers) WriteRequest(clientCTX client.ClientContext, codec protocol.ClientCodec, conn interface{}, method string, params interface{}, id interface{}) error {
|
||||
func (crwch *ClientReadWriteCloseHandlers) WriteRequest(clientCTX client.ClientContext, codec protocol.ClientCodec, conn interface{}, method string, params []interface{}, id interface{}) error {
|
||||
soc := conn.(csc.Socket)
|
||||
|
||||
if wErr := codec.WriteRequest(soc, method, params, id); nil != wErr {
|
||||
|
|
|
@ -34,7 +34,7 @@ func (crwch *ClientReadWriteCloseHandlers) ReadResponse(clientCTX client.ClientC
|
|||
return resCodec, err
|
||||
}
|
||||
|
||||
func (crwch *ClientReadWriteCloseHandlers) WriteRequest(clientCTX client.ClientContext, codec protocol.ClientCodec, conn interface{}, method string, params interface{}, id interface{}) error {
|
||||
func (crwch *ClientReadWriteCloseHandlers) WriteRequest(clientCTX client.ClientContext, codec protocol.ClientCodec, conn interface{}, method string, params []interface{}, id interface{}) error {
|
||||
soc := conn.(cwfc.Socket)
|
||||
|
||||
wc, wErr := soc.NextWriter(websocket.TextMessage)
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
// ClientCodec creates a ClientCodecRequest to process each request.
|
||||
type ClientCodec interface {
|
||||
WriteRequest(w io.Writer, method string, args interface{}, id interface{}) error
|
||||
WriteRequest(w io.Writer, method string, args []interface{}, id interface{}) error
|
||||
NewResponse(rc io.Reader) (ClientResponseCodec, error)
|
||||
}
|
||||
|
||||
|
|
12
protocol/error.go
Normal file
12
protocol/error.go
Normal file
|
@ -0,0 +1,12 @@
|
|||
package protocol
|
||||
|
||||
type ErrorCode int
|
||||
|
||||
const (
|
||||
E_PARSE ErrorCode = -32700
|
||||
E_INVALID_REQ ErrorCode = -32600
|
||||
E_NO_METHOD ErrorCode = -32601
|
||||
E_BAD_PARAMS ErrorCode = -32602
|
||||
E_INTERNAL ErrorCode = -32603
|
||||
E_SERVER ErrorCode = -32000
|
||||
)
|
|
@ -27,11 +27,16 @@ type ClientCodec struct {
|
|||
codecSel codec.CodecSelector
|
||||
}
|
||||
|
||||
func (cc *ClientCodec) WriteRequest(w io.Writer, method string, args interface{}, id interface{}) error {
|
||||
func (cc *ClientCodec) WriteRequest(w io.Writer, method string, args []interface{}, id interface{}) error {
|
||||
params, err := convertParamsToStringArray(args)
|
||||
if nil != err {
|
||||
return err
|
||||
}
|
||||
|
||||
req := &clientRequest{
|
||||
Version: Version,
|
||||
Method: method,
|
||||
Params: args,
|
||||
Params: params,
|
||||
ID: id,
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
|
||||
"git.loafle.net/commons_go/rpc/codec"
|
||||
crp "git.loafle.net/commons_go/rpc/protocol"
|
||||
cuej "git.loafle.net/commons_go/util/encoding/json"
|
||||
)
|
||||
|
||||
|
@ -35,7 +36,7 @@ func (cnc *ClientNotificationCodec) ReadParams(args []interface{}) error {
|
|||
// JSON params structured object. Unmarshal to the args object.
|
||||
if err := cuej.SetValueWithJSONStringArray(*cnc.noti.Params, args); nil != err {
|
||||
cnc.err = &Error{
|
||||
Code: E_INVALID_REQ,
|
||||
Code: crp.E_INVALID_REQ,
|
||||
Message: err.Error(),
|
||||
Data: cnc.noti.Params,
|
||||
}
|
||||
|
@ -48,18 +49,18 @@ func (cnc *ClientNotificationCodec) ReadParams(args []interface{}) error {
|
|||
|
||||
func (cnc *ClientNotificationCodec) Params() ([]string, error) {
|
||||
if cnc.err == nil && cnc.noti.Params != nil {
|
||||
var results []string
|
||||
var values []string
|
||||
|
||||
if err := json.Unmarshal(*cnc.noti.Params, &results); err != nil {
|
||||
if err := json.Unmarshal(*cnc.noti.Params, &values); err != nil {
|
||||
cnc.err = &Error{
|
||||
Code: E_INVALID_REQ,
|
||||
Code: crp.E_INVALID_REQ,
|
||||
Message: err.Error(),
|
||||
Data: cnc.noti.Params,
|
||||
}
|
||||
return nil, cnc.err
|
||||
}
|
||||
|
||||
return results, nil
|
||||
return values, nil
|
||||
}
|
||||
return nil, cnc.err
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"git.loafle.net/commons_go/rpc/codec"
|
||||
"git.loafle.net/commons_go/rpc/protocol"
|
||||
crp "git.loafle.net/commons_go/rpc/protocol"
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -35,7 +36,7 @@ func (crc *ClientResponseCodec) Result(result interface{}) error {
|
|||
if nil == crc.err && nil != crc.res.Result {
|
||||
if err := json.Unmarshal(*crc.res.Result, result); nil != err {
|
||||
crc.err = &Error{
|
||||
Code: E_PARSE,
|
||||
Code: crp.E_PARSE,
|
||||
Message: err.Error(),
|
||||
Data: crc.res.Result,
|
||||
}
|
||||
|
@ -77,14 +78,14 @@ func newClientResponseCodec(r io.Reader, codec codec.Codec) (protocol.ClientResp
|
|||
return nil, err
|
||||
}
|
||||
err = &Error{
|
||||
Code: E_PARSE,
|
||||
Code: crp.E_PARSE,
|
||||
Message: err.Error(),
|
||||
Data: res,
|
||||
}
|
||||
}
|
||||
if res.Version != Version {
|
||||
err = &Error{
|
||||
Code: E_INVALID_REQ,
|
||||
Code: crp.E_INVALID_REQ,
|
||||
Message: "jsonrpc must be " + Version,
|
||||
Data: res,
|
||||
}
|
||||
|
|
|
@ -2,24 +2,15 @@ package json
|
|||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
type ErrorCode int
|
||||
|
||||
const (
|
||||
E_PARSE ErrorCode = -32700
|
||||
E_INVALID_REQ ErrorCode = -32600
|
||||
E_NO_METHOD ErrorCode = -32601
|
||||
E_BAD_PARAMS ErrorCode = -32602
|
||||
E_INTERNAL ErrorCode = -32603
|
||||
E_SERVER ErrorCode = -32000
|
||||
crp "git.loafle.net/commons_go/rpc/protocol"
|
||||
)
|
||||
|
||||
var ErrNullResult = errors.New("result is null")
|
||||
|
||||
type Error struct {
|
||||
// A Number that indicates the error type that occurred.
|
||||
Code ErrorCode `json:"code"` /* required */
|
||||
Code crp.ErrorCode `json:"code"` /* required */
|
||||
|
||||
// A String providing a short description of the error.
|
||||
// The message SHOULD be limited to a concise single sentence.
|
||||
|
|
|
@ -35,8 +35,13 @@ func (sc *ServerCodec) NewRequest(r io.Reader) (protocol.ServerRequestCodec, err
|
|||
}
|
||||
|
||||
// WriteNotification send a notification from server to client.
|
||||
func (sc *ServerCodec) WriteNotification(w io.Writer, method string, args interface{}) error {
|
||||
noti := &serverNotification{Method: method, Params: args}
|
||||
func (sc *ServerCodec) WriteNotification(w io.Writer, method string, args []interface{}) error {
|
||||
params, err := convertParamsToStringArray(args)
|
||||
if nil != err {
|
||||
return err
|
||||
}
|
||||
|
||||
noti := &serverNotification{Method: method, Params: params}
|
||||
res := &serverResponse{Version: Version, Result: noti}
|
||||
|
||||
encoder := json.NewEncoder(sc.codecSel.SelectByWriter(w).Encode(w))
|
||||
|
|
|
@ -6,6 +6,8 @@ import (
|
|||
|
||||
"git.loafle.net/commons_go/rpc/codec"
|
||||
"git.loafle.net/commons_go/rpc/protocol"
|
||||
crp "git.loafle.net/commons_go/rpc/protocol"
|
||||
cuej "git.loafle.net/commons_go/util/encoding/json"
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -48,14 +50,14 @@ func newServerRequestCodec(r io.Reader, codec codec.Codec) (protocol.ServerReque
|
|||
}
|
||||
if err != nil {
|
||||
err = &Error{
|
||||
Code: E_PARSE,
|
||||
Code: crp.E_PARSE,
|
||||
Message: err.Error(),
|
||||
Data: req,
|
||||
}
|
||||
}
|
||||
if req.Version != Version {
|
||||
err = &Error{
|
||||
Code: E_INVALID_REQ,
|
||||
Code: crp.E_INVALID_REQ,
|
||||
Message: "jsonrpc must be " + Version,
|
||||
Data: req,
|
||||
}
|
||||
|
@ -93,65 +95,35 @@ func (src *ServerRequestCodec) Method() string {
|
|||
// case, to the method's expected parameters.
|
||||
func (src *ServerRequestCodec) ReadParams(args []interface{}) error {
|
||||
if src.err == nil && src.req.Params != nil {
|
||||
// Note: if src.req.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.
|
||||
var values []json.RawMessage
|
||||
if err := json.Unmarshal(*src.req.Params, &values); err != nil {
|
||||
if err := cuej.SetValueWithJSONStringArray(*src.req.Params, args); nil != err {
|
||||
src.err = &Error{
|
||||
Code: E_INVALID_REQ,
|
||||
Code: crp.E_INVALID_REQ,
|
||||
Message: err.Error(),
|
||||
Data: src.req.Params,
|
||||
}
|
||||
return src.err
|
||||
}
|
||||
|
||||
for indexI := 0; indexI < len(args); indexI++ {
|
||||
if err := json.Unmarshal(values[indexI], &args[indexI]); err != nil {
|
||||
src.err = &Error{
|
||||
Code: E_INVALID_REQ,
|
||||
Message: err.Error(),
|
||||
Data: src.req.Params,
|
||||
}
|
||||
return src.err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return src.err
|
||||
}
|
||||
|
||||
func (src *ServerRequestCodec) Params() ([]string, error) {
|
||||
if src.err == nil && src.req.Params != nil {
|
||||
var values []interface{}
|
||||
var values []string
|
||||
|
||||
if err := json.Unmarshal(*src.req.Params, &values); err != nil {
|
||||
src.err = &Error{
|
||||
Code: E_INVALID_REQ,
|
||||
Code: crp.E_INVALID_REQ,
|
||||
Message: err.Error(),
|
||||
Data: src.req.Params,
|
||||
}
|
||||
return nil, src.err
|
||||
}
|
||||
|
||||
var results []string
|
||||
for _, v := range values {
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
results = append(results, v)
|
||||
default:
|
||||
b, err := json.Marshal(v)
|
||||
if nil != err {
|
||||
src.err = &Error{
|
||||
Code: E_INVALID_REQ,
|
||||
Message: err.Error(),
|
||||
Data: src.req.Params,
|
||||
}
|
||||
return nil, src.err
|
||||
}
|
||||
results = append(results, string(b))
|
||||
}
|
||||
}
|
||||
|
||||
return results, nil
|
||||
return values, nil
|
||||
}
|
||||
return nil, src.err
|
||||
}
|
||||
|
@ -167,7 +139,7 @@ func (src *ServerRequestCodec) WriteError(w io.Writer, status int, err error) er
|
|||
jsonErr, ok := err.(*Error)
|
||||
if !ok {
|
||||
jsonErr = &Error{
|
||||
Code: E_SERVER,
|
||||
Code: crp.E_SERVER,
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
|
|
46
protocol/json/util.go
Normal file
46
protocol/json/util.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
package json
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
cur "git.loafle.net/commons_go/util/reflect"
|
||||
)
|
||||
|
||||
func convertParamsToStringArray(params []interface{}) ([]string, error) {
|
||||
var values []string
|
||||
if nil == params || 0 == len(params) {
|
||||
return values, nil
|
||||
}
|
||||
|
||||
for i, param := range params {
|
||||
t := reflect.TypeOf(param)
|
||||
switch t.Kind() {
|
||||
case reflect.String:
|
||||
values = append(values, param.(string))
|
||||
case reflect.Array, reflect.Slice, reflect.Map, reflect.Struct:
|
||||
b, err := json.Marshal(param)
|
||||
if nil != err {
|
||||
return nil, err
|
||||
}
|
||||
values = append(values, string(b))
|
||||
case reflect.Ptr:
|
||||
if t.Elem().Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("Pointer of param[%d] is permitted only Struct type", i)
|
||||
}
|
||||
b, err := json.Marshal(param)
|
||||
if nil != err {
|
||||
return nil, err
|
||||
}
|
||||
values = append(values, string(b))
|
||||
default:
|
||||
s, err := cur.ConvertToString(param)
|
||||
if nil != err {
|
||||
return nil, fmt.Errorf("String conversion of param[%d] has been failed [%v]", i, err)
|
||||
}
|
||||
values = append(values, s)
|
||||
}
|
||||
}
|
||||
return values, nil
|
||||
}
|
|
@ -7,7 +7,7 @@ import (
|
|||
// ServerCodec creates a ServerRequestCodec to process each request.
|
||||
type ServerCodec interface {
|
||||
NewRequest(r io.Reader) (ServerRequestCodec, error)
|
||||
WriteNotification(w io.Writer, method string, args interface{}) error
|
||||
WriteNotification(w io.Writer, method string, args []interface{}) error
|
||||
}
|
||||
|
||||
// ServerRequestCodec decodes a request and encodes a response using a specific
|
||||
|
|
|
@ -37,7 +37,7 @@ func (srwch *ServletReadWriteCloseHandlers) WriteResponse(servletCTX rpc.Servlet
|
|||
return nil
|
||||
}
|
||||
|
||||
func (srwch *ServletReadWriteCloseHandlers) WriteNotification(servletCTX rpc.ServletContext, conn interface{}, codec protocol.ServerCodec, method string, params interface{}) error {
|
||||
func (srwch *ServletReadWriteCloseHandlers) WriteNotification(servletCTX rpc.ServletContext, conn interface{}, codec protocol.ServerCodec, method string, params []interface{}) error {
|
||||
soc := conn.(server.Socket)
|
||||
|
||||
if wErr := codec.WriteNotification(soc, method, params); nil != wErr {
|
||||
|
|
|
@ -49,7 +49,7 @@ func (srwch *ServletReadWriteCloseHandlers) WriteResponse(servletCTX rpc.Servlet
|
|||
return nil
|
||||
}
|
||||
|
||||
func (srwch *ServletReadWriteCloseHandlers) WriteNotification(servletCTX rpc.ServletContext, conn interface{}, codec protocol.ServerCodec, method string, params interface{}) error {
|
||||
func (srwch *ServletReadWriteCloseHandlers) WriteNotification(servletCTX rpc.ServletContext, conn interface{}, codec protocol.ServerCodec, method string, params []interface{}) error {
|
||||
soc := conn.(cwf.Socket)
|
||||
|
||||
wc, wErr := soc.NextWriter(websocket.TextMessage)
|
||||
|
|
|
@ -270,5 +270,5 @@ type responseState struct {
|
|||
|
||||
type notification struct {
|
||||
method string
|
||||
args interface{}
|
||||
args []interface{}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import "git.loafle.net/commons_go/rpc/protocol"
|
|||
type ServletReadWriteCloseHandler interface {
|
||||
ReadRequest(servletCTX ServletContext, codec protocol.ServerCodec, conn interface{}) (protocol.ServerRequestCodec, error)
|
||||
WriteResponse(servletCTX ServletContext, conn interface{}, requestCodec protocol.ServerRequestCodec, result interface{}, err error) error
|
||||
WriteNotification(servletCTX ServletContext, conn interface{}, codec protocol.ServerCodec, method string, params interface{}) error
|
||||
WriteNotification(servletCTX ServletContext, conn interface{}, codec protocol.ServerCodec, method string, params []interface{}) error
|
||||
|
||||
Validate()
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ func (srwch *ServletReadWriteCloseHandlers) WriteResponse(servletCTX ServletCont
|
|||
return fmt.Errorf("Servlet RWC Handler: WriteResponse is not implemented")
|
||||
}
|
||||
|
||||
func (srwch *ServletReadWriteCloseHandlers) WriteNotification(servletCTX ServletContext, conn interface{}, codec protocol.ServerCodec, method string, params interface{}) error {
|
||||
func (srwch *ServletReadWriteCloseHandlers) WriteNotification(servletCTX ServletContext, conn interface{}, codec protocol.ServerCodec, method string, params []interface{}) error {
|
||||
return fmt.Errorf("Servlet RWC Handler: WriteNotification is not implemented")
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user