using System; using System.Collections.Generic; using Newtonsoft.Json; using LeanCloud.Storage.Internal.Codec; using LeanCloud.Storage.Internal; namespace LeanCloud.Realtime { /// /// 已知类型消息 /// public class LCIMTypedMessage : LCIMMessage { /// /// 文本消息 /// public const int TextMessageType = -1; /// /// 图像消息 /// public const int ImageMessageType = -2; /// /// 音频消息 /// public const int AudioMessageType = -3; /// /// 视频消息 /// public const int VideoMessageType = -4; /// /// 位置消息 /// public const int LocationMessageType = -5; /// /// 文件消息 /// public const int FileMessageType = -6; /// /// 撤回消息 /// public const int RecalledMessageType = -127; /// /// 保留字段 /// protected const string MessageTypeKey = "_lctype"; protected const string MessageAttributesKey = "_lcattrs"; protected const string MessageTextKey = "_lctext"; protected const string MessageLocationKey = "_lcloc"; protected const string MessageFileKey = "_lcfile"; protected const string MessageDataLongitudeKey = "longitude"; protected const string MessageDataLatitudeKey = "latitude"; protected const string MessageDataObjectIdKey = "objId"; protected const string MessageDataUrlKey = "url"; protected const string MessageDataMetaDataKey = "metaData"; protected const string MessageDataMetaNameKey = "name"; protected const string MessageDataMetaFormatKey = "format"; protected const string MessageDataMetaSizeKey = "size"; protected const string MessageDataMetaWidthKey = "width"; protected const string MessageDataMetaHeightKey = "height"; protected const string MessageDataMetaDurationKey = "duration"; private Dictionary customProperties; /// /// 完整的消息数据 /// protected Dictionary data = new Dictionary(); /// /// 消息类型 /// public virtual int MessageType { get; private set; } /// /// 消息属性访问 /// /// /// public object this[string key] { get { if (customProperties == null) { return null; } return customProperties[key]; } set { if (customProperties == null) { customProperties = new Dictionary(); } customProperties[key] = value; } } protected LCIMTypedMessage() { } internal virtual Dictionary Encode() { Dictionary msgData = data != null ? new Dictionary(data) : new Dictionary(); msgData[MessageTypeKey] = MessageType; if (customProperties != null && customProperties.Count > 0) { msgData[MessageAttributesKey] = LCEncoder.Encode(customProperties); } return msgData; } internal virtual void Decode(Dictionary msgData) { // 直接保存 data = msgData; } internal static LCIMTypedMessage Deserialize(string json) { Dictionary msgData = JsonConvert.DeserializeObject>(json, new LCJsonConverter()); LCIMTypedMessage message = null; int msgType = (int)msgData[MessageTypeKey]; if (customMessageDict.TryGetValue(msgType, out Func msgConstructor)) { // 已注册的类型消息 message = msgConstructor.Invoke(); } else { // 未注册的类型消息 message = new LCIMTypedMessage(); } // 已知类型消息的固定 message.MessageType = msgType; if (msgData.TryGetValue(MessageAttributesKey, out object attrObj)) { message.customProperties = LCDecoder.Decode(attrObj) as Dictionary; } message.Decode(msgData); return message; } // 内置已知类型消息 static readonly Dictionary> customMessageDict = new Dictionary> { { TextMessageType, () => new LCIMTextMessage() }, { ImageMessageType, () => new LCIMImageMessage() }, { AudioMessageType, () => new LCIMAudioMessage() }, { VideoMessageType, () => new LCIMVideoMessage() }, { LocationMessageType, () => new LCIMLocationMessage() }, { FileMessageType, () => new LCIMFileMessage() }, { RecalledMessageType, () => new LCIMRecalledMessage() } }; /// /// 注册自定义类型消息 /// /// /// /// public static void Register(int msgType, Func msgConstructor) where T : LCIMTypedMessage { customMessageDict[msgType] = msgConstructor; } } }