rpc/protocol/json/client_notification.go
crusader 2286a5021e ing
2017-11-26 19:15:51 +09:00

98 lines
2.7 KiB
Go

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)
}