1 Star 0 Fork 1

Collin / leaf

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
json.go 4.00 KB
一键复制 编辑 原始数据 按行查看 历史
Collin 提交于 2021-10-06 20:48 . update package
package json
import (
"encoding/json"
"errors"
"fmt"
"reflect"
"gitee.com/nbcx/leaf/chanrpc"
"gitee.com/nbcx/leaf/log"
)
type Processor struct {
msgInfo map[string]*MsgInfo
}
type MsgInfo struct {
msgType reflect.Type
msgRouter *chanrpc.Server
msgHandler MsgHandler
msgRawHandler MsgHandler
}
type MsgHandler func([]interface{})
type MsgRaw struct {
msgID string
msgRawData json.RawMessage
}
func NewProcessor() *Processor {
p := new(Processor)
p.msgInfo = make(map[string]*MsgInfo)
return p
}
// It's dangerous to call the method on routing or marshaling (unmarshaling)
func (p *Processor) Register(msg interface{}) string {
msgType := reflect.TypeOf(msg)
if msgType == nil || msgType.Kind() != reflect.Ptr {
log.Fatal("json message pointer required")
}
msgID := msgType.Elem().Name()
if msgID == "" {
log.Fatal("unnamed json message")
}
if _, ok := p.msgInfo[msgID]; ok {
log.Fatal("message %v is already registered", msgID)
}
i := new(MsgInfo)
i.msgType = msgType
p.msgInfo[msgID] = i
return msgID
}
// It's dangerous to call the method on routing or marshaling (unmarshaling)
func (p *Processor) SetRouter(msg interface{}, msgRouter *chanrpc.Server) {
msgType := reflect.TypeOf(msg)
if msgType == nil || msgType.Kind() != reflect.Ptr {
log.Fatal("json message pointer required")
}
msgID := msgType.Elem().Name()
i, ok := p.msgInfo[msgID]
if !ok {
log.Fatal("message %v not registered", msgID)
}
i.msgRouter = msgRouter
}
// It's dangerous to call the method on routing or marshaling (unmarshaling)
func (p *Processor) SetHandler(msg interface{}, msgHandler MsgHandler) {
msgType := reflect.TypeOf(msg)
if msgType == nil || msgType.Kind() != reflect.Ptr {
log.Fatal("json message pointer required")
}
msgID := msgType.Elem().Name()
i, ok := p.msgInfo[msgID]
if !ok {
log.Fatal("message %v not registered", msgID)
}
i.msgHandler = msgHandler
}
// It's dangerous to call the method on routing or marshaling (unmarshaling)
func (p *Processor) SetRawHandler(msgID string, msgRawHandler MsgHandler) {
i, ok := p.msgInfo[msgID]
if !ok {
log.Fatal("message %v not registered", msgID)
}
i.msgRawHandler = msgRawHandler
}
// goroutine safe
func (p *Processor) Route(msg interface{}, userData interface{}) error {
// raw
if msgRaw, ok := msg.(MsgRaw); ok {
i, ok := p.msgInfo[msgRaw.msgID]
if !ok {
return fmt.Errorf("message %v not registered", msgRaw.msgID)
}
if i.msgRawHandler != nil {
i.msgRawHandler([]interface{}{msgRaw.msgID, msgRaw.msgRawData, userData})
}
return nil
}
// json
msgType := reflect.TypeOf(msg)
if msgType == nil || msgType.Kind() != reflect.Ptr {
return errors.New("json message pointer required")
}
msgID := msgType.Elem().Name()
i, ok := p.msgInfo[msgID]
if !ok {
return fmt.Errorf("message %v not registered", msgID)
}
if i.msgHandler != nil {
i.msgHandler([]interface{}{msg, userData})
}
if i.msgRouter != nil {
i.msgRouter.Go(msgType, msg, userData)
}
return nil
}
// goroutine safe
func (p *Processor) Unmarshal(data []byte) (interface{}, error) {
var m map[string]json.RawMessage
err := json.Unmarshal(data, &m)
if err != nil {
return nil, err
}
if len(m) != 1 {
return nil, errors.New("invalid json data")
}
for msgID, data := range m {
i, ok := p.msgInfo[msgID]
if !ok {
return nil, fmt.Errorf("message %v not registered", msgID)
}
// msg
if i.msgRawHandler != nil {
return MsgRaw{msgID, data}, nil
} else {
msg := reflect.New(i.msgType.Elem()).Interface()
return msg, json.Unmarshal(data, msg)
}
}
panic("bug")
}
// goroutine safe
func (p *Processor) Marshal(msg interface{}) ([][]byte, error) {
msgType := reflect.TypeOf(msg)
if msgType == nil || msgType.Kind() != reflect.Ptr {
return nil, errors.New("json message pointer required")
}
msgID := msgType.Elem().Name()
if _, ok := p.msgInfo[msgID]; !ok {
return nil, fmt.Errorf("message %v not registered", msgID)
}
// data
m := map[string]interface{}{msgID: msg}
data, err := json.Marshal(m)
return [][]byte{data}, err
}
1
https://gitee.com/nbcx/leaf.git
git@gitee.com:nbcx/leaf.git
nbcx
leaf
leaf
78613ecb5808

搜索帮助