116 lines
2.4 KiB
Go
116 lines
2.4 KiB
Go
package protocol
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
type typePeek struct {
|
|
V int `json:"v"`
|
|
Type string `json:"type"`
|
|
}
|
|
|
|
// Decode 解析一帧 MQTT/应用 JSON,返回具体类型。
|
|
func Decode(data []byte) (any, error) {
|
|
var peek typePeek
|
|
if err := Unmarshal(data, &peek); err != nil {
|
|
return nil, badRequest("invalid json")
|
|
}
|
|
if peek.V != 0 && peek.V != Version {
|
|
return nil, badRequest("unsupported version")
|
|
}
|
|
if peek.Type == "" {
|
|
return nil, badRequest("missing type")
|
|
}
|
|
|
|
var out any
|
|
switch peek.Type {
|
|
case TypeHello:
|
|
out = &Hello{}
|
|
case TypeResp:
|
|
out = &Resp{}
|
|
case TypeSend:
|
|
out = &Send{}
|
|
case TypeMsg:
|
|
out = &Msg{}
|
|
case TypeAck:
|
|
out = &Ack{}
|
|
case TypeRecall:
|
|
out = &Recall{}
|
|
case TypeStatus:
|
|
out = &Status{}
|
|
case TypeReceipt:
|
|
out = &Receipt{}
|
|
case TypeReceiptAck:
|
|
out = &ReceiptAck{}
|
|
case TypeRevoked:
|
|
out = &Revoked{}
|
|
case TypePresenceGet:
|
|
out = &PresenceGet{}
|
|
case TypeDirectoryList:
|
|
out = &DirectoryList{}
|
|
case TypePresenceWatch:
|
|
out = &PresenceWatch{}
|
|
case TypePresence:
|
|
out = &Presence{}
|
|
case TypeUnlock:
|
|
out = &Unlock{}
|
|
case TypeSelfGet:
|
|
out = &SelfGet{}
|
|
case TypeSelfUpdate:
|
|
out = &SelfUpdate{}
|
|
case TypeSelfTalkPassword:
|
|
out = &SelfTalkPassword{}
|
|
case TypeSelfLoginPassword:
|
|
out = &SelfLoginPassword{}
|
|
case TypeSelfLogout:
|
|
out = &SelfLogout{}
|
|
case TypeGroupCreate:
|
|
out = &GroupCreate{}
|
|
case TypeGroupAdd:
|
|
out = &GroupAdd{}
|
|
case TypeGroupRemove:
|
|
out = &GroupRemove{}
|
|
case TypeGroupLeave:
|
|
out = &GroupLeave{}
|
|
case TypeGroupTransfer:
|
|
out = &GroupTransfer{}
|
|
case TypeGroupRename:
|
|
out = &GroupRename{}
|
|
case TypeGroupDissolve:
|
|
out = &GroupDissolve{}
|
|
case TypeGroupList:
|
|
out = &GroupList{}
|
|
case TypeGroupGet:
|
|
out = &GroupGet{}
|
|
case TypeGroupEvent:
|
|
out = &GroupEvent{}
|
|
case TypeFatal:
|
|
out = &Fatal{}
|
|
default:
|
|
return nil, badRequest(fmt.Sprintf("unknown type %q", peek.Type))
|
|
}
|
|
if err := Unmarshal(data, out); err != nil {
|
|
return nil, badRequest("invalid json for type")
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
// DecodeRegister 解析注册 HTTP 请求体。
|
|
func DecodeRegister(data []byte) (*RegisterRequest, error) {
|
|
var req RegisterRequest
|
|
if err := Unmarshal(data, &req); err != nil {
|
|
return nil, badRequest("invalid json")
|
|
}
|
|
return &req, nil
|
|
}
|
|
|
|
// MustRaw 将值编码为 json.RawMessage(用于填 Resp.Data)。
|
|
func MustRaw(v any) json.RawMessage {
|
|
b, err := Marshal(v)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return b
|
|
}
|