ing
This commit is contained in:
		
							parent
							
								
									c6be50ff2c
								
							
						
					
					
						commit
						00dff62f10
					
				@ -17,6 +17,7 @@ type CallState struct {
 | 
				
			|||||||
	Error    error
 | 
						Error    error
 | 
				
			||||||
	DoneChan chan *CallState
 | 
						DoneChan chan *CallState
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hasResponse bool
 | 
				
			||||||
	canceled    uint32
 | 
						canceled    uint32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -24,9 +24,9 @@ type Client interface {
 | 
				
			|||||||
	Connect() error
 | 
						Connect() error
 | 
				
			||||||
	Close()
 | 
						Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Notify(method string, args interface{}) error
 | 
						Notify(method string, args ...interface{}) (err error)
 | 
				
			||||||
	Call(method string, args interface{}, result interface{}) error
 | 
						Call(result interface{}, method string, args ...interface{}) error
 | 
				
			||||||
	CallTimeout(method string, args interface{}, result interface{}, timeout time.Duration) (err error)
 | 
						CallTimeout(timeout time.Duration, result interface{}, method string, args ...interface{}) (err error)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type client struct {
 | 
					type client struct {
 | 
				
			||||||
@ -73,18 +73,28 @@ func (c *client) Close() {
 | 
				
			|||||||
	c.stopChan = nil
 | 
						c.stopChan = nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *client) Notify(method string, args interface{}) error {
 | 
					func (c *client) Notify(method string, args ...interface{}) (err error) {
 | 
				
			||||||
	_, err := c.send(method, args, nil, false, true)
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *client) Call(method string, args interface{}, result interface{}) error {
 | 
					 | 
				
			||||||
	return c.CallTimeout(method, args, result, c.ch.GetRequestTimeout())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (c *client) CallTimeout(method string, args interface{}, result interface{}, timeout time.Duration) (err error) {
 | 
					 | 
				
			||||||
	var cs *CallState
 | 
						var cs *CallState
 | 
				
			||||||
	if cs, err = c.send(method, args, result, true, true); nil != err {
 | 
						if cs, err = c.send(true, false, nil, method, args...); nil != err {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						select {
 | 
				
			||||||
 | 
						case <-cs.DoneChan:
 | 
				
			||||||
 | 
							err = cs.Error
 | 
				
			||||||
 | 
							releaseCallState(cs)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *client) Call(result interface{}, method string, args ...interface{}) error {
 | 
				
			||||||
 | 
						return c.CallTimeout(c.ch.GetRequestTimeout(), result, method, args...)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *client) CallTimeout(timeout time.Duration, result interface{}, method string, args ...interface{}) (err error) {
 | 
				
			||||||
 | 
						var cs *CallState
 | 
				
			||||||
 | 
						if cs, err = c.send(true, true, result, method, args...); nil != err {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -104,7 +114,7 @@ func (c *client) CallTimeout(method string, args interface{}, result interface{}
 | 
				
			|||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *client) send(method string, args interface{}, result interface{}, hasResponse bool, usePool bool) (cs *CallState, err error) {
 | 
					func (c *client) send(usePool bool, hasResponse bool, result interface{}, method string, args ...interface{}) (cs *CallState, err error) {
 | 
				
			||||||
	if !hasResponse {
 | 
						if !hasResponse {
 | 
				
			||||||
		usePool = true
 | 
							usePool = true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -115,13 +125,14 @@ func (c *client) send(method string, args interface{}, result interface{}, hasRe
 | 
				
			|||||||
		cs = &CallState{}
 | 
							cs = &CallState{}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cs.hasResponse = hasResponse
 | 
				
			||||||
	cs.Method = method
 | 
						cs.Method = method
 | 
				
			||||||
	cs.Args = args
 | 
						cs.Args = args
 | 
				
			||||||
 | 
						cs.DoneChan = make(chan *CallState, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if hasResponse {
 | 
						if hasResponse {
 | 
				
			||||||
		cs.ID = c.ch.GetRequestID()
 | 
							cs.ID = c.ch.GetRequestID()
 | 
				
			||||||
		cs.Result = result
 | 
							cs.Result = result
 | 
				
			||||||
		cs.DoneChan = make(chan *CallState, 1)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	select {
 | 
						select {
 | 
				
			||||||
@ -242,7 +253,7 @@ func (c *client) rpcWriter(stopChan <-chan struct{}, writerDone chan<- error) {
 | 
				
			|||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if nil != cs.DoneChan {
 | 
							if cs.hasResponse {
 | 
				
			||||||
			c.pendingRequestsLock.Lock()
 | 
								c.pendingRequestsLock.Lock()
 | 
				
			||||||
			n := len(c.pendingRequests)
 | 
								n := len(c.pendingRequests)
 | 
				
			||||||
			c.pendingRequests[cs.ID] = cs
 | 
								c.pendingRequests[cs.ID] = cs
 | 
				
			||||||
@ -256,8 +267,9 @@ func (c *client) rpcWriter(stopChan <-chan struct{}, writerDone chan<- error) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		err = c.ch.GetCodec().Write(c.conn, cs.Method, cs.Args, cs.ID)
 | 
							err = c.ch.GetCodec().Write(c.conn, cs.Method, cs.Args, cs.ID)
 | 
				
			||||||
		if nil == cs.DoneChan {
 | 
							if !cs.hasResponse {
 | 
				
			||||||
			releaseCallState(cs)
 | 
								cs.Error = err
 | 
				
			||||||
 | 
								cs.done()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if nil != err {
 | 
							if nil != err {
 | 
				
			||||||
			err = fmt.Errorf("Client: Cannot send request to wire: [%s]", err)
 | 
								err = fmt.Errorf("Client: Cannot send request to wire: [%s]", err)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								gateway/gateway.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								gateway/gateway.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					package gateway
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"git.loafle.net/commons_go/server"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func New(sh ServerHandler) server.Server {
 | 
				
			||||||
 | 
						s := server.New(sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return s
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								gateway/rpc_gateway_handler.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								gateway/rpc_gateway_handler.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					package gateway
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"git.loafle.net/commons_go/rpc/protocol"
 | 
				
			||||||
 | 
						"git.loafle.net/commons_go/rpc/server"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type RPCGetewayHandler interface {
 | 
				
			||||||
 | 
						server.RPCServerHandler
 | 
				
			||||||
 | 
						Handle(codecReq protocol.ServerCodecRequest) (interface{}, error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								gateway/rpc_gateway_handlers.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								gateway/rpc_gateway_handlers.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					package gateway
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"git.loafle.net/commons_go/rpc/protocol"
 | 
				
			||||||
 | 
						"git.loafle.net/commons_go/rpc/server"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type RPCGetewayHandlers struct {
 | 
				
			||||||
 | 
						server.RPCServerHandlers
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (rpcGH *RPCGetewayHandlers) Handle(codecReq protocol.ServerCodecRequest) (result interface{}, err error) {
 | 
				
			||||||
 | 
						return nil, errors.New("RPC Gateway: Handler method[Handle] is not implement")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (rpcGH *RPCGetewayHandlers) Validate() {
 | 
				
			||||||
 | 
						rpcGH.RPCServerHandlers.Validate()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										67
									
								
								gateway/server_handlers.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								gateway/server_handlers.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					package gateway
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"git.loafle.net/commons_go/server"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ServerHandlers struct {
 | 
				
			||||||
 | 
						server.ServerHandlers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						RPCGetewayHandler RPCGetewayHandler
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (sh *ServerHandlers) Handle(conn net.Conn, stopChan <-chan struct{}, doneChan chan<- struct{}) {
 | 
				
			||||||
 | 
						contentType := sh.RPCGetewayHandler.GetContentType(conn)
 | 
				
			||||||
 | 
						codec, err := sh.RPCGetewayHandler.GetCodec(contentType)
 | 
				
			||||||
 | 
						if nil != err {
 | 
				
			||||||
 | 
							log.Printf("RPC Handle: %v", err)
 | 
				
			||||||
 | 
							doneChan <- struct{}{}
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							sh.RPCGetewayHandler.OnPreRead(conn)
 | 
				
			||||||
 | 
							// Create a new codec request.
 | 
				
			||||||
 | 
							codecReq, errNew := codec.NewRequest(conn)
 | 
				
			||||||
 | 
							if nil != errNew {
 | 
				
			||||||
 | 
								if sh.IsClientDisconnect(errNew) {
 | 
				
			||||||
 | 
									doneChan <- struct{}{}
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								log.Printf("RPC Handle: %v", errNew)
 | 
				
			||||||
 | 
								doneChan <- struct{}{}
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							sh.RPCGetewayHandler.OnPostRead(conn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							result, err := sh.RPCGetewayHandler.Handle(codecReq)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if nil != err {
 | 
				
			||||||
 | 
								sh.RPCGetewayHandler.OnPreWriteError(conn, err)
 | 
				
			||||||
 | 
								codecReq.WriteError(conn, 400, err)
 | 
				
			||||||
 | 
								sh.RPCGetewayHandler.OnPostWriteError(conn, err)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								sh.RPCGetewayHandler.OnPreWriteResult(conn, result)
 | 
				
			||||||
 | 
								codecReq.WriteResponse(conn, result)
 | 
				
			||||||
 | 
								sh.RPCGetewayHandler.OnPostWriteResult(conn, result)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							select {
 | 
				
			||||||
 | 
							case <-stopChan:
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (sh *ServerHandlers) Validate() {
 | 
				
			||||||
 | 
						sh.ServerHandlers.Validate()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if nil == sh.RPCGetewayHandler {
 | 
				
			||||||
 | 
							panic("RPCGetewayHandler must be specified.")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -47,17 +47,11 @@ func (ccn *ClientCodecNotify) Method() string {
 | 
				
			|||||||
	return ccn.notify.Method
 | 
						return ccn.notify.Method
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ccn *ClientCodecNotify) ReadParams(args interface{}) error {
 | 
					func (ccn *ClientCodecNotify) ReadParams(args []interface{}) error {
 | 
				
			||||||
	if ccn.err == nil && ccn.notify.Params != nil {
 | 
						if ccn.err == nil && ccn.notify.Params != nil {
 | 
				
			||||||
		// 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 := json.Unmarshal(*ccn.notify.Params, args); err != nil {
 | 
							if err := json.Unmarshal(*ccn.notify.Params, args); err != nil {
 | 
				
			||||||
			// Clearly JSON params is not a structured object,
 | 
					 | 
				
			||||||
			// fallback and attempt an unmarshal with JSON params as
 | 
					 | 
				
			||||||
			// array value and RPC params is struct. Unmarshal into
 | 
					 | 
				
			||||||
			// array containing the request struct.
 | 
					 | 
				
			||||||
			params := [1]interface{}{args}
 | 
					 | 
				
			||||||
			if err = json.Unmarshal(*ccn.notify.Params, ¶ms); err != nil {
 | 
					 | 
				
			||||||
			ccn.err = &Error{
 | 
								ccn.err = &Error{
 | 
				
			||||||
				Code:    E_INVALID_REQ,
 | 
									Code:    E_INVALID_REQ,
 | 
				
			||||||
				Message: err.Error(),
 | 
									Message: err.Error(),
 | 
				
			||||||
@ -65,7 +59,6 @@ func (ccn *ClientCodecNotify) ReadParams(args interface{}) error {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return ccn.err
 | 
						return ccn.err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -160,7 +160,7 @@ func (scr *ServerCodecRequest) Method() string {
 | 
				
			|||||||
// absence of expected names MAY result in an error being
 | 
					// absence of expected names MAY result in an error being
 | 
				
			||||||
// generated. The names MUST match exactly, including
 | 
					// generated. The names MUST match exactly, including
 | 
				
			||||||
// case, to the method's expected parameters.
 | 
					// case, to the method's expected parameters.
 | 
				
			||||||
func (scr *ServerCodecRequest) ReadParams(args interface{}) error {
 | 
					func (scr *ServerCodecRequest) ReadParams(args []interface{}) error {
 | 
				
			||||||
	if scr.err == nil && scr.request.Params != nil {
 | 
						if scr.err == nil && scr.request.Params != nil {
 | 
				
			||||||
		// 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.
 | 
				
			||||||
@ -169,8 +169,6 @@ func (scr *ServerCodecRequest) ReadParams(args interface{}) error {
 | 
				
			|||||||
			// fallback and attempt an unmarshal with JSON params as
 | 
								// fallback and attempt an unmarshal with JSON params as
 | 
				
			||||||
			// array value and RPC params is struct. Unmarshal into
 | 
								// array value and RPC params is struct. Unmarshal into
 | 
				
			||||||
			// array containing the request struct.
 | 
								// array containing the request struct.
 | 
				
			||||||
			params := [1]interface{}{args}
 | 
					 | 
				
			||||||
			if err = json.Unmarshal(*scr.request.Params, ¶ms); err != nil {
 | 
					 | 
				
			||||||
			scr.err = &Error{
 | 
								scr.err = &Error{
 | 
				
			||||||
				Code:    E_INVALID_REQ,
 | 
									Code:    E_INVALID_REQ,
 | 
				
			||||||
				Message: err.Error(),
 | 
									Message: err.Error(),
 | 
				
			||||||
@ -178,7 +176,6 @@ func (scr *ServerCodecRequest) ReadParams(args interface{}) error {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return scr.err
 | 
						return scr.err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,6 @@ type RegistryCodec interface {
 | 
				
			|||||||
	// Reads the request and returns the RPC method name.
 | 
						// Reads the request and returns the RPC method name.
 | 
				
			||||||
	Method() string
 | 
						Method() string
 | 
				
			||||||
	// Reads the request filling the RPC method args.
 | 
						// Reads the request filling the RPC method args.
 | 
				
			||||||
	ReadParams(interface{}) error
 | 
						ReadParams([]interface{}) error
 | 
				
			||||||
	Complete()
 | 
						Complete()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										39
									
								
								registry.go
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								registry.go
									
									
									
									
									
								
							@ -75,28 +75,31 @@ func (rr *rpcRegistry) Invoke(codec protocol.RegistryCodec) (result interface{},
 | 
				
			|||||||
		return nil, errGet
 | 
							return nil, errGet
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Decode the args.
 | 
						// Decode the args.
 | 
				
			||||||
	args := reflect.New(methodSpec.argsType)
 | 
					
 | 
				
			||||||
	if errRead := codec.ReadParams(args.Interface()); errRead != nil {
 | 
						var in []reflect.Value
 | 
				
			||||||
 | 
						paramValues, paramInstances := methodSpec.getParams()
 | 
				
			||||||
 | 
						if nil != paramValues {
 | 
				
			||||||
 | 
							in = make([]reflect.Value, len(paramValues)+1)
 | 
				
			||||||
 | 
							if errRead := codec.ReadParams(paramInstances); errRead != nil {
 | 
				
			||||||
			return nil, errRead
 | 
								return nil, errRead
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							for indexI := 0; indexI < len(paramValues); indexI++ {
 | 
				
			||||||
 | 
								in[indexI+1] = paramValues[indexI]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							in = make([]reflect.Value, 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						in[0] = serviceSpec.rcvr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Call the service method.
 | 
						// Call the service method.
 | 
				
			||||||
	reply := reflect.New(methodSpec.replyType)
 | 
						returnValues := methodSpec.method.Func.Call(in)
 | 
				
			||||||
	errValue := methodSpec.method.Func.Call([]reflect.Value{
 | 
					 | 
				
			||||||
		serviceSpec.rcvr,
 | 
					 | 
				
			||||||
		args,
 | 
					 | 
				
			||||||
		reply,
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Cast the result to error if needed.
 | 
						if nil != methodSpec.returnType {
 | 
				
			||||||
	var errResult error
 | 
							result = returnValues[0].Interface()
 | 
				
			||||||
	errInter := errValue[0].Interface()
 | 
							err = returnValues[1].Interface().(error)
 | 
				
			||||||
	if errInter != nil {
 | 
						} else {
 | 
				
			||||||
		errResult = errInter.(error)
 | 
							err = returnValues[0].Interface().(error)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if errResult != nil {
 | 
						return
 | 
				
			||||||
		return nil, errResult
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return reply.Interface(), nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,6 @@ type RPCServerHandler interface {
 | 
				
			|||||||
	OnPreWriteError(w io.Writer, err error)
 | 
						OnPreWriteError(w io.Writer, err error)
 | 
				
			||||||
	OnPostWriteError(w io.Writer, err error)
 | 
						OnPostWriteError(w io.Writer, err error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	getCodec(contentType string) (protocol.ServerCodec, error)
 | 
						GetCodec(contentType string) (protocol.ServerCodec, error)
 | 
				
			||||||
	invoke(codec protocol.RegistryCodec) (result interface{}, err error)
 | 
						invoke(codec protocol.RegistryCodec) (result interface{}, err error)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -60,7 +60,7 @@ func (rpcSH *RPCServerHandlers) Validate() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (rpcSH *RPCServerHandlers) getCodec(contentType string) (protocol.ServerCodec, error) {
 | 
					func (rpcSH *RPCServerHandlers) GetCodec(contentType string) (protocol.ServerCodec, error) {
 | 
				
			||||||
	var codec protocol.ServerCodec
 | 
						var codec protocol.ServerCodec
 | 
				
			||||||
	if contentType == "" && len(rpcSH.codecs) == 1 {
 | 
						if contentType == "" && len(rpcSH.codecs) == 1 {
 | 
				
			||||||
		// If Content-Type is not set and only one codec has been registered,
 | 
							// If Content-Type is not set and only one codec has been registered,
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,7 @@ type ServerHandlers struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (sh *ServerHandlers) Handle(conn net.Conn, stopChan <-chan struct{}, doneChan chan<- struct{}) {
 | 
					func (sh *ServerHandlers) Handle(conn net.Conn, stopChan <-chan struct{}, doneChan chan<- struct{}) {
 | 
				
			||||||
	contentType := sh.RPCServerHandler.GetContentType(conn)
 | 
						contentType := sh.RPCServerHandler.GetContentType(conn)
 | 
				
			||||||
	codec, err := sh.RPCServerHandler.getCodec(contentType)
 | 
						codec, err := sh.RPCServerHandler.GetCodec(contentType)
 | 
				
			||||||
	if nil != err {
 | 
						if nil != err {
 | 
				
			||||||
		log.Printf("RPC Handle: %v", err)
 | 
							log.Printf("RPC Handle: %v", err)
 | 
				
			||||||
		doneChan <- struct{}{}
 | 
							doneChan <- struct{}{}
 | 
				
			||||||
 | 
				
			|||||||
@ -27,10 +27,26 @@ type service struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type serviceMethod struct {
 | 
					type serviceMethod struct {
 | 
				
			||||||
	method     reflect.Method // receiver method
 | 
						method     reflect.Method // receiver method
 | 
				
			||||||
	argsType  reflect.Type   // type of the request argument
 | 
						paramTypes []reflect.Type // type of the request argument
 | 
				
			||||||
	replyType reflect.Type   // type of the response argument
 | 
						returnType reflect.Type   // type of the response argument
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (sm *serviceMethod) getParams() (values []reflect.Value, instances []interface{}) {
 | 
				
			||||||
 | 
						if nil == sm.paramTypes || 0 == len(sm.paramTypes) {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pCount := len(sm.paramTypes)
 | 
				
			||||||
 | 
						values = make([]reflect.Value, pCount)
 | 
				
			||||||
 | 
						instances = make([]interface{}, pCount)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for indexI := 0; indexI < pCount; indexI++ {
 | 
				
			||||||
 | 
							values[indexI] = reflect.New(sm.paramTypes[indexI])
 | 
				
			||||||
 | 
							instances[indexI] = values[indexI].Interface()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ----------------------------------------------------------------------------
 | 
					// ----------------------------------------------------------------------------
 | 
				
			||||||
// serviceMap
 | 
					// serviceMap
 | 
				
			||||||
@ -63,6 +79,7 @@ func (m *serviceMap) register(rcvr interface{}, name string) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Setup methods.
 | 
						// Setup methods.
 | 
				
			||||||
 | 
					Loop:
 | 
				
			||||||
	for i := 0; i < s.rcvrType.NumMethod(); i++ {
 | 
						for i := 0; i < s.rcvrType.NumMethod(); i++ {
 | 
				
			||||||
		method := s.rcvrType.Method(i)
 | 
							method := s.rcvrType.Method(i)
 | 
				
			||||||
		mtype := method.Type
 | 
							mtype := method.Type
 | 
				
			||||||
@ -70,37 +87,48 @@ func (m *serviceMap) register(rcvr interface{}, name string) error {
 | 
				
			|||||||
		if method.PkgPath != "" {
 | 
							if method.PkgPath != "" {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// Method needs four ins: receiver, *args, *reply.
 | 
					
 | 
				
			||||||
		if mtype.NumIn() != 3 {
 | 
							var paramTypes []reflect.Type
 | 
				
			||||||
			continue
 | 
					
 | 
				
			||||||
 | 
							mCount := mtype.NumIn()
 | 
				
			||||||
 | 
							if 0 < mCount {
 | 
				
			||||||
 | 
								paramTypes = make([]reflect.Type, mCount)
 | 
				
			||||||
 | 
								for indexI := 0; indexI < mCount; indexI++ {
 | 
				
			||||||
 | 
									param := mtype.In(indexI)
 | 
				
			||||||
 | 
									if !isExportedOrBuiltin(param) {
 | 
				
			||||||
 | 
										continue Loop
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
		// First argument must be a pointer and must be exported.
 | 
									paramTypes[indexI] = param.Elem()
 | 
				
			||||||
		args := mtype.In(1)
 | 
					 | 
				
			||||||
		if args.Kind() != reflect.Ptr || !isExportedOrBuiltin(args) {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		// Second argument must be a pointer and must be exported.
 | 
							}
 | 
				
			||||||
		reply := mtype.In(2)
 | 
					
 | 
				
			||||||
		if reply.Kind() != reflect.Ptr || !isExportedOrBuiltin(reply) {
 | 
							var returnType reflect.Type
 | 
				
			||||||
 | 
							switch mtype.NumOut() {
 | 
				
			||||||
 | 
							case 1:
 | 
				
			||||||
 | 
								if returnType := mtype.Out(0); returnType != typeOfError {
 | 
				
			||||||
 | 
									continue Loop
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case 2:
 | 
				
			||||||
 | 
								if returnType := mtype.Out(0); !isExportedOrBuiltin(returnType) {
 | 
				
			||||||
 | 
									continue Loop
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if returnType := mtype.Out(1); returnType != typeOfError {
 | 
				
			||||||
 | 
									continue Loop
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								returnType = mtype.Out(1).Elem()
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Method needs one out: error.
 | 
					 | 
				
			||||||
		if mtype.NumOut() != 1 {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if returnType := mtype.Out(0); returnType != typeOfError {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		s.methods[method.Name] = &serviceMethod{
 | 
							s.methods[method.Name] = &serviceMethod{
 | 
				
			||||||
			method:     method,
 | 
								method:     method,
 | 
				
			||||||
			argsType:  args.Elem(),
 | 
								paramTypes: paramTypes,
 | 
				
			||||||
			replyType: reply.Elem(),
 | 
								returnType: returnType,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(s.methods) == 0 {
 | 
						if len(s.methods) == 0 {
 | 
				
			||||||
		return fmt.Errorf("rpc: %q has no exported methods of suitable type",
 | 
							return fmt.Errorf("rpc: %q has no exported methods of suitable type", s.name)
 | 
				
			||||||
			s.name)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Add to the map.
 | 
						// Add to the map.
 | 
				
			||||||
	m.mutex.Lock()
 | 
						m.mutex.Lock()
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user