package json import ( "encoding/json" "sync" "git.loafle.net/commons_go/rpc/codec" "git.loafle.net/commons_go/rpc/protocol" ) // ---------------------------------------------------------------------------- // ClientNotificationCodec // ---------------------------------------------------------------------------- // clientRequest represents a JSON-RPC notification sent to a client. type clientNotification struct { // 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 *json.RawMessage `json:"params,omitempty"` } // newClientNotificationCodec returns a new ClientNotificationCodec. func newClientNotificationCodec(raw *json.RawMessage, codec codec.Codec) (protocol.ClientNotificationCodec, error) { // Decode the request body and check if RPC method is valid. cnc := retainClientNotificationCodec() if err := json.Unmarshal(*raw, &cnc.notification); nil != err { releaseClientNotificationCodec(cnc) return nil, err } return cnc, nil } // ClientNotificationCodec decodes and encodes a single notification. type ClientNotificationCodec struct { notification clientNotification err error } func (crc *ClientNotificationCodec) Method() string { return crc.notification.Method } func (crc *ClientNotificationCodec) ReadParams(args []interface{}) error { if crc.err == nil && crc.notification.Params != nil { // 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. if err := json.Unmarshal(*crc.notification.Params, &args); err != nil { crc.err = &Error{ Code: E_INVALID_REQ, Message: err.Error(), Data: crc.notification.Params, } } } return crc.err } func (crc *ClientNotificationCodec) Params() ([]string, error) { if crc.err == nil && crc.notification.Params != nil { var results []string if err := json.Unmarshal(*crc.notification.Params, &results); err != nil { crc.err = &Error{ Code: E_INVALID_REQ, Message: err.Error(), Data: crc.notification.Params, } return nil, crc.err } return results, nil } return nil, crc.err } func (crc *ClientNotificationCodec) Close() { releaseClientNotificationCodec(crc) } var clientNotificationCodecPool sync.Pool func retainClientNotificationCodec() *ClientNotificationCodec { v := clientNotificationCodecPool.Get() if v == nil { return &ClientNotificationCodec{} } return v.(*ClientNotificationCodec) } func releaseClientNotificationCodec(crc *ClientNotificationCodec) { crc.notification.Method = "" crc.notification.Params = nil clientNotificationCodecPool.Put(crc) }