package json import ( "encoding/base64" "encoding/json" "errors" "fmt" "git.bvbej.com/bvbej/base-golang/pkg/websocket/codec" ) type jsonCodec struct{} type jsonReq struct { Router string `json:"router"` Data []byte `json:"data"` Error string `json:"error,omitempty"` } type jsonAck struct { Router string `json:"router"` Data string `json:"data"` Error string `json:"error,omitempty"` } func init() { codec.RegisterCodec("json_codec", new(jsonCodec)) } func (*jsonCodec) Marshal(router string, dataPtr any, retErr error) ([]byte, error) { if router == "" { return nil, fmt.Errorf("marshal: router is empty") } if dataPtr == nil && retErr == nil { return nil, fmt.Errorf("marshal data in package is nil. router:%s dt:%T", router, dataPtr) } ack := &jsonAck{ Router: router, } if dataPtr != nil { data, err := json.Marshal(dataPtr) if err != nil { return nil, fmt.Errorf("marshal json marshal failed. routerr:%s dt:%T err:%v", router, dataPtr, err) } ack.Data = base64.StdEncoding.EncodeToString(data) } if retErr != nil { ack.Error = retErr.Error() } ackByte, err := json.Marshal(ack) if err != nil { return nil, fmt.Errorf("marshal json marshal failed. routerr:%s dt:%T err:%v", router, dataPtr, err) } return ackByte, nil } func (*jsonCodec) Unmarshal(msg []byte) (int, *codec.MsgPack, error) { var i = len(msg) req := &jsonReq{} err := json.Unmarshal(msg, req) if err != nil { return i, nil, errors.New("unmarshal split message id failed") } var router = req.Router msgPack := &codec.MsgPack{Router: router} dt := codec.GetMessage(router) if dt == nil { return i, nil, fmt.Errorf("unmarshal message not registed. router:%s", router) } if req.Data != nil { err = json.Unmarshal(req.Data, dt) if err != nil { return i, nil, fmt.Errorf("unmarshal json unmarshal failed. dt:%T msg:%s err:%v", dt, string(msg), err) } } msgPack.DataPtr = dt if req.Error != "" { msgPack.Err = errors.New(req.Error) } return i, msgPack, nil } func (*jsonCodec) ToString(data any) string { ab, err := json.Marshal(data) if err != nil { return fmt.Sprintf("invalid type %T", data) } return string(ab) }