* LCIMMessage.cs:
* LCIMFileMessage.cs: * LCIMTextMessage.cs: * LCIMAudioMessage.cs: * LCIMImageMessage.cs: * LCIMTypedMessage.cs: * LCIMBinaryMessage.cs: * LCIMLocationMessage.cs: * LCIMRecalledMessage.cs: * LCIMMessageController.cs: * LCIMVideoMessage.cs: chore: 重构并支持自定义类型消息
parent
5379ee1285
commit
fb830691c4
|
@ -32,7 +32,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
|
|||
} else if (message is LCIMBinaryMessage binaryMessage) {
|
||||
direct.BinaryMsg = ByteString.CopyFrom(binaryMessage.Data);
|
||||
} else {
|
||||
throw new ArgumentException("Message MUST BE LCIMTypedMessage or LCIMBinaryMessage.");
|
||||
throw new ArgumentException("Message MUST be LCIMTypedMessage or LCIMBinaryMessage.");
|
||||
}
|
||||
// 暂态消息
|
||||
if (options.Transient) {
|
||||
|
|
|
@ -2,14 +2,15 @@
|
|||
using LeanCloud.Storage;
|
||||
|
||||
namespace LeanCloud.Realtime {
|
||||
/// <summary>
|
||||
/// 音频消息
|
||||
/// </summary>
|
||||
public class LCIMAudioMessage : LCIMFileMessage {
|
||||
/// <summary>
|
||||
/// 时长
|
||||
/// </summary>
|
||||
public double Duration {
|
||||
get {
|
||||
if (double.TryParse(File.MetaData["duration"] as string, out double duration)) {
|
||||
return duration;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
get; private set;
|
||||
}
|
||||
|
||||
internal LCIMAudioMessage() {
|
||||
|
@ -21,14 +22,22 @@ namespace LeanCloud.Realtime {
|
|||
|
||||
internal override Dictionary<string, object> Encode() {
|
||||
Dictionary<string, object> data = base.Encode();
|
||||
Dictionary<string, object> fileData = data["_lcfile"] as Dictionary<string, object>;
|
||||
Dictionary<string, object> metaData = fileData["metaData"] as Dictionary<string, object>;
|
||||
if (File.MetaData.TryGetValue("duration", out object duration)) {
|
||||
metaData["duration"] = duration;
|
||||
Dictionary<string, object> fileData = data[MessageFileKey] as Dictionary<string, object>;
|
||||
Dictionary<string, object> metaData = fileData[MessageDataMetaDataKey] as Dictionary<string, object>;
|
||||
if (File.MetaData.TryGetValue(MessageDataMetaDurationKey, out object duration)) {
|
||||
metaData[MessageDataMetaDurationKey] = duration;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
internal override int MessageType => AudioMessageType;
|
||||
internal override void Decode(Dictionary<string, object> msgData) {
|
||||
base.Decode(msgData);
|
||||
if (File.MetaData.TryGetValue(MessageDataMetaDurationKey, out object duration) &&
|
||||
double.TryParse(duration as string, out double d)) {
|
||||
Duration = d;
|
||||
}
|
||||
}
|
||||
|
||||
public override int MessageType => AudioMessageType;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
namespace LeanCloud.Realtime {
|
||||
/// <summary>
|
||||
/// 二进制消息
|
||||
/// </summary>
|
||||
public class LCIMBinaryMessage : LCIMMessage {
|
||||
/// <summary>
|
||||
/// 消息数据
|
||||
/// </summary>
|
||||
public byte[] Data {
|
||||
get; internal set;
|
||||
}
|
||||
|
|
|
@ -3,29 +3,41 @@ using System.Collections.Generic;
|
|||
using LeanCloud.Storage;
|
||||
|
||||
namespace LeanCloud.Realtime {
|
||||
/// <summary>
|
||||
/// 文件消息
|
||||
/// </summary>
|
||||
public class LCIMFileMessage : LCIMTextMessage {
|
||||
/// <summary>
|
||||
/// 文件
|
||||
/// </summary>
|
||||
public LCFile File {
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 文件大小
|
||||
/// </summary>
|
||||
public int Size {
|
||||
get {
|
||||
if (int.TryParse(File.MetaData["size"] as string, out int size)) {
|
||||
if (int.TryParse(File.MetaData[MessageDataMetaSizeKey] as string, out int size)) {
|
||||
return size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 文件类型
|
||||
/// </summary>
|
||||
public string Format {
|
||||
get {
|
||||
if (File.MetaData.TryGetValue("format", out object format)) {
|
||||
return format as string;
|
||||
}
|
||||
return "unknown/unknown";
|
||||
return File.MimeType;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 文件链接
|
||||
/// </summary>
|
||||
public string Url {
|
||||
get {
|
||||
return File.Url;
|
||||
|
@ -40,41 +52,46 @@ namespace LeanCloud.Realtime {
|
|||
File = file;
|
||||
}
|
||||
|
||||
internal override int MessageType => FileMessageType;
|
||||
public override int MessageType => FileMessageType;
|
||||
|
||||
internal override Dictionary<string, object> Encode() {
|
||||
if (File == null) {
|
||||
throw new Exception("File MUST NOT be null before sent.");
|
||||
}
|
||||
Dictionary<string, object> fileData = new Dictionary<string, object> {
|
||||
{ "objId", File.ObjectId },
|
||||
{ "url", File.Url },
|
||||
{ "metaData", new Dictionary<string, object> {
|
||||
{ "name", File.Name },
|
||||
{ "format", File.MimeType }
|
||||
{ MessageDataObjectIdKey, File.ObjectId },
|
||||
{ MessageDataUrlKey, File.Url },
|
||||
{ MessageDataMetaDataKey, new Dictionary<string, object> {
|
||||
{ MessageDataMetaNameKey, File.Name },
|
||||
{ MessageDataMetaFormatKey, File.MimeType }
|
||||
} }
|
||||
};
|
||||
if (File.MetaData.TryGetValue("size", out object size)) {
|
||||
Dictionary<string, object> metaData = fileData["metaData"] as Dictionary<string, object>;
|
||||
metaData["size"] = size;
|
||||
if (File.MetaData.TryGetValue(MessageDataMetaSizeKey, out object size)) {
|
||||
Dictionary<string, object> metaData = fileData[MessageDataMetaDataKey] as Dictionary<string, object>;
|
||||
metaData[MessageDataMetaSizeKey] = size;
|
||||
}
|
||||
Dictionary<string, object> data = base.Encode();
|
||||
data["_lcfile"] = fileData;
|
||||
data[MessageFileKey] = fileData;
|
||||
return data;
|
||||
}
|
||||
|
||||
protected override void DecodeMessageData(Dictionary<string, object> msgData) {
|
||||
base.DecodeMessageData(msgData);
|
||||
Dictionary<string, object> fileData = msgData["_lcfile"] as Dictionary<string, object>;
|
||||
string objectId = fileData["objId"] as string;
|
||||
File = LCObject.CreateWithoutData(LCFile.CLASS_NAME, objectId) as LCFile;
|
||||
if (fileData.TryGetValue("url", out object url)) {
|
||||
File.Url = url as string;
|
||||
}
|
||||
if (fileData.TryGetValue("metaData", out object metaData)) {
|
||||
File.MetaData = metaData as Dictionary<string, object>;
|
||||
if (File.MetaData.TryGetValue("name", out object name)) {
|
||||
File.Name = name as string;
|
||||
internal override void Decode(Dictionary<string, object> msgData) {
|
||||
base.Decode(msgData);
|
||||
|
||||
if (msgData.TryGetValue(MessageFileKey, out object fileDataObject)) {
|
||||
Dictionary<string, object> fileData = fileDataObject as Dictionary<string, object>;
|
||||
if (fileData.TryGetValue(MessageDataObjectIdKey, out object objectIdObject)) {
|
||||
string objectId = objectIdObject as string;
|
||||
File = LCObject.CreateWithoutData(LCFile.CLASS_NAME, objectId) as LCFile;
|
||||
if (fileData.TryGetValue(MessageDataUrlKey, out object url)) {
|
||||
File.Url = url as string;
|
||||
}
|
||||
if (fileData.TryGetValue(MessageDataMetaDataKey, out object metaData)) {
|
||||
File.MetaData = metaData as Dictionary<string, object>;
|
||||
if (File.MetaData.TryGetValue(MessageDataMetaNameKey, out object name)) {
|
||||
File.Name = name as string;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,23 +2,22 @@
|
|||
using LeanCloud.Storage;
|
||||
|
||||
namespace LeanCloud.Realtime {
|
||||
/// <summary>
|
||||
/// 图像消息
|
||||
/// </summary>
|
||||
public class LCIMImageMessage : LCIMFileMessage {
|
||||
/// <summary>
|
||||
/// 图像宽度
|
||||
/// </summary>
|
||||
public int Width {
|
||||
get {
|
||||
if (int.TryParse(File.MetaData["width"] as string, out int width)) {
|
||||
return width;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
get; private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 图像高度
|
||||
/// </summary>
|
||||
public int Height {
|
||||
get {
|
||||
if (int.TryParse(File.MetaData["height"] as string, out int height)) {
|
||||
return height;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
get; private set;
|
||||
}
|
||||
|
||||
internal LCIMImageMessage() : base() {
|
||||
|
@ -30,17 +29,29 @@ namespace LeanCloud.Realtime {
|
|||
|
||||
internal override Dictionary<string, object> Encode() {
|
||||
Dictionary<string, object> data = base.Encode();
|
||||
Dictionary<string, object> fileData = data["_lcfile"] as Dictionary<string, object>;
|
||||
Dictionary<string, object> metaData = fileData["metaData"] as Dictionary<string, object>;
|
||||
if (File.MetaData.TryGetValue("width", out object width)) {
|
||||
metaData["width"] = width;
|
||||
Dictionary<string, object> fileData = data[MessageFileKey] as Dictionary<string, object>;
|
||||
Dictionary<string, object> metaData = fileData[MessageDataMetaDataKey] as Dictionary<string, object>;
|
||||
if (File.MetaData.TryGetValue(MessageDataMetaWidthKey, out object width)) {
|
||||
metaData[MessageDataMetaWidthKey] = width;
|
||||
}
|
||||
if (File.MetaData.TryGetValue("height", out object height)) {
|
||||
metaData["height"] = height;
|
||||
if (File.MetaData.TryGetValue(MessageDataMetaHeightKey, out object height)) {
|
||||
metaData[MessageDataMetaHeightKey] = height;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
internal override int MessageType => ImageMessageType;
|
||||
internal override void Decode(Dictionary<string, object> msgData) {
|
||||
base.Decode(msgData);
|
||||
if (File.MetaData.TryGetValue(MessageDataMetaWidthKey, out object width) &&
|
||||
int.TryParse(width as string, out int w)) {
|
||||
Width = w;
|
||||
}
|
||||
if (File.MetaData.TryGetValue(MessageDataMetaHeightKey, out object height) &&
|
||||
int.TryParse(height as string, out int h)) {
|
||||
Height = h;
|
||||
}
|
||||
}
|
||||
|
||||
public override int MessageType => ImageMessageType;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,13 @@
|
|||
using LeanCloud.Storage;
|
||||
|
||||
namespace LeanCloud.Realtime {
|
||||
/// <summary>
|
||||
/// 位置消息
|
||||
/// </summary>
|
||||
public class LCIMLocationMessage : LCIMTextMessage {
|
||||
/// <summary>
|
||||
/// 位置
|
||||
/// </summary>
|
||||
public LCGeoPoint Location {
|
||||
get; set;
|
||||
}
|
||||
|
@ -17,19 +23,30 @@ namespace LeanCloud.Realtime {
|
|||
internal override Dictionary<string, object> Encode() {
|
||||
Dictionary<string, object> data = base.Encode();
|
||||
Dictionary<string, object> locationData = new Dictionary<string, object> {
|
||||
{ "longitude", Location.Longitude },
|
||||
{ "latitude", Location.Latitude }
|
||||
{ MessageDataLongitudeKey, Location.Longitude },
|
||||
{ MessageDataLatitudeKey, Location.Latitude }
|
||||
};
|
||||
data["_lcloc"] = locationData;
|
||||
data[MessageLocationKey] = locationData;
|
||||
return data;
|
||||
}
|
||||
|
||||
protected override void DecodeMessageData(Dictionary<string, object> msgData) {
|
||||
base.DecodeMessageData(msgData);
|
||||
Dictionary<string, object> locationData = msgData["_lcloc"] as Dictionary<string, object>;
|
||||
Location = new LCGeoPoint((double)locationData["latitude"], (double)locationData["longitude"]);
|
||||
internal override void Decode(Dictionary<string, object> msgData) {
|
||||
base.Decode(msgData);
|
||||
if (msgData.TryGetValue(MessageLocationKey, out object val)) {
|
||||
Dictionary<string, object> locationData = val as Dictionary<string, object>;
|
||||
double latitude = 0, longitude = 0;
|
||||
if (locationData.TryGetValue(MessageDataLatitudeKey, out object lat) &&
|
||||
double.TryParse(lat as string, out double la)) {
|
||||
latitude = la;
|
||||
}
|
||||
if (locationData.TryGetValue(MessageDataLongitudeKey, out object lon) &&
|
||||
double.TryParse(lon as string, out double lo)) {
|
||||
longitude = lo;
|
||||
}
|
||||
Location = new LCGeoPoint(latitude, longitude);
|
||||
}
|
||||
}
|
||||
|
||||
internal override int MessageType => LocationMessageType;
|
||||
public override int MessageType => LocationMessageType;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,31 +2,41 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace LeanCloud.Realtime {
|
||||
/// <summary>
|
||||
/// 消息基类
|
||||
/// </summary>
|
||||
public abstract class LCIMMessage {
|
||||
internal const int TextMessageType = -1;
|
||||
internal const int ImageMessageType = -2;
|
||||
internal const int AudioMessageType = -3;
|
||||
internal const int VideoMessageType = -4;
|
||||
internal const int LocationMessageType = -5;
|
||||
internal const int FileMessageType = -6;
|
||||
internal const int RecalledMessageType = -127;
|
||||
|
||||
/// <summary>
|
||||
/// 消息所在对话 Id
|
||||
/// </summary>
|
||||
public string ConversationId {
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 消息 Id
|
||||
/// </summary>
|
||||
public string Id {
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送者 Id
|
||||
/// </summary>
|
||||
public string FromClientId {
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送时间戳
|
||||
/// </summary>
|
||||
public long SentTimestamp {
|
||||
get; internal set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送时间
|
||||
/// </summary>
|
||||
public DateTime SentAt {
|
||||
get {
|
||||
return DateTimeOffset.FromUnixTimeMilliseconds(SentTimestamp)
|
||||
|
@ -34,10 +44,16 @@ namespace LeanCloud.Realtime {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 送达时间戳
|
||||
/// </summary>
|
||||
public long DeliveredTimestamp {
|
||||
get; internal set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 送达时间
|
||||
/// </summary>
|
||||
public DateTime DeliveredAt {
|
||||
get {
|
||||
return DateTimeOffset.FromUnixTimeMilliseconds(DeliveredTimestamp)
|
||||
|
@ -45,10 +61,16 @@ namespace LeanCloud.Realtime {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 已读时间戳
|
||||
/// </summary>
|
||||
public long ReadTimestamp {
|
||||
get; internal set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 已读时间
|
||||
/// </summary>
|
||||
public DateTime ReadAt {
|
||||
get {
|
||||
return DateTimeOffset.FromUnixTimeMilliseconds(ReadTimestamp)
|
||||
|
@ -56,10 +78,16 @@ namespace LeanCloud.Realtime {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改时间戳
|
||||
/// </summary>
|
||||
public long PatchedTimestamp {
|
||||
get; internal set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改时间
|
||||
/// </summary>
|
||||
public DateTime PatchedAt {
|
||||
get {
|
||||
return DateTimeOffset.FromUnixTimeMilliseconds(PatchedTimestamp)
|
||||
|
@ -67,18 +95,30 @@ namespace LeanCloud.Realtime {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提醒成员 Id 列表
|
||||
/// </summary>
|
||||
public List<string> MentionIdList {
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否提醒所有人
|
||||
/// </summary>
|
||||
public bool MentionAll {
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否提醒当前用户
|
||||
/// </summary>
|
||||
public bool Mentioned {
|
||||
get; internal set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是暂态消息
|
||||
/// </summary>
|
||||
public bool IsTransient {
|
||||
get; internal set;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,6 @@ namespace LeanCloud.Realtime {
|
|||
public LCIMRecalledMessage() {
|
||||
}
|
||||
|
||||
internal override int MessageType => RecalledMessageType;
|
||||
public override int MessageType => RecalledMessageType;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace LeanCloud.Realtime {
|
||||
/// <summary>
|
||||
/// 文本消息
|
||||
/// </summary>
|
||||
public class LCIMTextMessage : LCIMTypedMessage {
|
||||
/// <summary>
|
||||
/// 文本
|
||||
/// </summary>
|
||||
public string Text {
|
||||
get; set;
|
||||
}
|
||||
|
@ -16,16 +22,16 @@ namespace LeanCloud.Realtime {
|
|||
internal override Dictionary<string, object> Encode() {
|
||||
Dictionary<string, object> data = base.Encode();
|
||||
if (!string.IsNullOrEmpty(Text)) {
|
||||
data["_lctext"] = Text;
|
||||
data[MessageTextKey] = Text;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
internal override int MessageType => TextMessageType;
|
||||
public override int MessageType => TextMessageType;
|
||||
|
||||
protected override void DecodeMessageData(Dictionary<string, object> msgData) {
|
||||
base.DecodeMessageData(msgData);
|
||||
if (msgData.TryGetValue("_lctext", out object value)) {
|
||||
internal override void Decode(Dictionary<string, object> msgData) {
|
||||
base.Decode(msgData);
|
||||
if (msgData.TryGetValue(MessageTextKey, out object value)) {
|
||||
Text = value as string;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,85 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using LeanCloud.Storage.Internal.Codec;
|
||||
using LeanCloud.Storage.Internal;
|
||||
|
||||
namespace LeanCloud.Realtime {
|
||||
public abstract class LCIMTypedMessage : LCIMMessage {
|
||||
/// <summary>
|
||||
/// 已知类型消息
|
||||
/// </summary>
|
||||
public class LCIMTypedMessage : LCIMMessage {
|
||||
/// <summary>
|
||||
/// 文本消息
|
||||
/// </summary>
|
||||
public const int TextMessageType = -1;
|
||||
/// <summary>
|
||||
/// 图像消息
|
||||
/// </summary>
|
||||
public const int ImageMessageType = -2;
|
||||
/// <summary>
|
||||
/// 音频消息
|
||||
/// </summary>
|
||||
public const int AudioMessageType = -3;
|
||||
/// <summary>
|
||||
/// 视频消息
|
||||
/// </summary>
|
||||
public const int VideoMessageType = -4;
|
||||
/// <summary>
|
||||
/// 位置消息
|
||||
/// </summary>
|
||||
public const int LocationMessageType = -5;
|
||||
/// <summary>
|
||||
/// 文件消息
|
||||
/// </summary>
|
||||
public const int FileMessageType = -6;
|
||||
/// <summary>
|
||||
/// 撤回消息
|
||||
/// </summary>
|
||||
public const int RecalledMessageType = -127;
|
||||
|
||||
/// <summary>
|
||||
/// 保留字段
|
||||
/// </summary>
|
||||
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<string, object> customProperties;
|
||||
|
||||
internal virtual int MessageType {
|
||||
/// <summary>
|
||||
/// 完整的消息数据
|
||||
/// </summary>
|
||||
protected Dictionary<string, object> data = new Dictionary<string, object>();
|
||||
|
||||
/// <summary>
|
||||
/// 消息类型
|
||||
/// </summary>
|
||||
public virtual int MessageType {
|
||||
get; private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 消息属性访问
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public object this[string key] {
|
||||
get {
|
||||
if (customProperties == null) {
|
||||
|
@ -30,18 +99,19 @@ namespace LeanCloud.Realtime {
|
|||
}
|
||||
|
||||
internal virtual Dictionary<string, object> Encode() {
|
||||
Dictionary<string, object> msgData = new Dictionary<string, object> {
|
||||
{ "_lctype", MessageType }
|
||||
};
|
||||
Dictionary<string, object> msgData = data != null ?
|
||||
new Dictionary<string, object>(data) : new Dictionary<string, object>();
|
||||
msgData[MessageTypeKey] = MessageType;
|
||||
if (customProperties != null && customProperties.Count > 0) {
|
||||
msgData["_lcattrs"] = LCEncoder.Encode(customProperties);
|
||||
msgData[MessageAttributesKey] = LCEncoder.Encode(customProperties);
|
||||
}
|
||||
return msgData;
|
||||
}
|
||||
|
||||
protected virtual void DecodeMessageData(Dictionary<string, object> msgData) {
|
||||
MessageType = (int)msgData["_lctype"];
|
||||
if (msgData.TryGetValue("_lcattrs", out object attrObj)) {
|
||||
internal virtual void Decode(Dictionary<string, object> msgData) {
|
||||
data = msgData;
|
||||
MessageType = (int)msgData[MessageTypeKey];
|
||||
if (msgData.TryGetValue(MessageAttributesKey, out object attrObj)) {
|
||||
customProperties = LCDecoder.Decode(attrObj) as Dictionary<string, object>;
|
||||
}
|
||||
}
|
||||
|
@ -50,36 +120,38 @@ namespace LeanCloud.Realtime {
|
|||
Dictionary<string, object> msgData = JsonConvert.DeserializeObject<Dictionary<string, object>>(json,
|
||||
new LCJsonConverter());
|
||||
LCIMTypedMessage message = null;
|
||||
int msgType = (int)msgData["_lctype"];
|
||||
switch (msgType) {
|
||||
case TextMessageType:
|
||||
message = new LCIMTextMessage();
|
||||
break;
|
||||
case ImageMessageType:
|
||||
message = new LCIMImageMessage();
|
||||
break;
|
||||
case AudioMessageType:
|
||||
message = new LCIMAudioMessage();
|
||||
break;
|
||||
case VideoMessageType:
|
||||
message = new LCIMVideoMessage();
|
||||
break;
|
||||
case LocationMessageType:
|
||||
message = new LCIMLocationMessage();
|
||||
break;
|
||||
case FileMessageType:
|
||||
message = new LCIMFileMessage();
|
||||
break;
|
||||
case RecalledMessageType:
|
||||
message = new LCIMRecalledMessage();
|
||||
break;
|
||||
default:
|
||||
// TODO 用户自定义类型消息
|
||||
|
||||
break;
|
||||
int msgType = (int)msgData[MessageTypeKey];
|
||||
if (customMessageDict.TryGetValue(msgType, out Func<LCIMTypedMessage> msgConstructor)) {
|
||||
// 已注册的类型消息
|
||||
message = msgConstructor.Invoke();
|
||||
} else {
|
||||
// 未注册的类型消息
|
||||
message = new LCIMTypedMessage();
|
||||
}
|
||||
message.DecodeMessageData(msgData);
|
||||
message.Decode(msgData);
|
||||
return message;
|
||||
}
|
||||
|
||||
// 内置已知类型消息
|
||||
static readonly Dictionary<int, Func<LCIMTypedMessage>> customMessageDict = new Dictionary<int, Func<LCIMTypedMessage>> {
|
||||
{ TextMessageType, () => new LCIMTextMessage() },
|
||||
{ ImageMessageType, () => new LCIMImageMessage() },
|
||||
{ AudioMessageType, () => new LCIMAudioMessage() },
|
||||
{ VideoMessageType, () => new LCIMVideoMessage() },
|
||||
{ LocationMessageType, () => new LCIMLocationMessage() },
|
||||
{ FileMessageType, () => new LCIMFileMessage() },
|
||||
{ RecalledMessageType, () => new LCIMRecalledMessage() }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 注册自定义类型消息
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="msgType"></param>
|
||||
/// <param name="msgConstructor"></param>
|
||||
public static void Register<T>(int msgType, Func<T> msgConstructor)
|
||||
where T : LCIMTypedMessage {
|
||||
customMessageDict[msgType] = msgConstructor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,29 @@
|
|||
using LeanCloud.Storage;
|
||||
|
||||
namespace LeanCloud.Realtime {
|
||||
/// <summary>
|
||||
/// 视频消息
|
||||
/// </summary>
|
||||
public class LCIMVideoMessage : LCIMFileMessage {
|
||||
/// <summary>
|
||||
/// 宽度
|
||||
/// </summary>
|
||||
public int Width {
|
||||
get; private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 高度
|
||||
/// </summary>
|
||||
public int Height {
|
||||
get; private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 时长
|
||||
/// </summary>
|
||||
public double Duration {
|
||||
get {
|
||||
if (double.TryParse(File.MetaData["duration"] as string, out double duration)) {
|
||||
return duration;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
get; private set;
|
||||
}
|
||||
|
||||
internal LCIMVideoMessage() {
|
||||
|
@ -21,20 +36,36 @@ namespace LeanCloud.Realtime {
|
|||
|
||||
internal override Dictionary<string, object> Encode() {
|
||||
Dictionary<string, object> data = base.Encode();
|
||||
Dictionary<string, object> fileData = data["_lcfile"] as Dictionary<string, object>;
|
||||
Dictionary<string, object> metaData = fileData["metaData"] as Dictionary<string, object>;
|
||||
if (File.MetaData.TryGetValue("width", out object width)) {
|
||||
metaData["width"] = width;
|
||||
Dictionary<string, object> fileData = data[MessageFileKey] as Dictionary<string, object>;
|
||||
Dictionary<string, object> metaData = fileData[MessageDataMetaDataKey] as Dictionary<string, object>;
|
||||
if (File.MetaData.TryGetValue(MessageDataMetaWidthKey, out object width)) {
|
||||
metaData[MessageDataMetaWidthKey] = width;
|
||||
}
|
||||
if (File.MetaData.TryGetValue("height", out object height)) {
|
||||
metaData["height"] = height;
|
||||
if (File.MetaData.TryGetValue(MessageDataMetaHeightKey, out object height)) {
|
||||
metaData[MessageDataMetaHeightKey] = height;
|
||||
}
|
||||
if (File.MetaData.TryGetValue("duration", out object duration)) {
|
||||
metaData["duration"] = duration;
|
||||
if (File.MetaData.TryGetValue(MessageDataMetaDurationKey, out object duration)) {
|
||||
metaData[MessageDataMetaDurationKey] = duration;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
internal override int MessageType => VideoMessageType;
|
||||
internal override void Decode(Dictionary<string, object> msgData) {
|
||||
base.Decode(msgData);
|
||||
if (File.MetaData.TryGetValue(MessageDataMetaWidthKey, out object width) &&
|
||||
int.TryParse(width as string, out int w)) {
|
||||
Width = w;
|
||||
}
|
||||
if (File.MetaData.TryGetValue(MessageDataMetaHeightKey, out object height) &&
|
||||
int.TryParse(height as string, out int h)) {
|
||||
Height = h;
|
||||
}
|
||||
if (File.MetaData.TryGetValue(MessageDataMetaDurationKey, out object duration) &&
|
||||
double.TryParse(duration as string, out double d)) {
|
||||
Duration = d;
|
||||
}
|
||||
}
|
||||
|
||||
public override int MessageType => VideoMessageType;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue