diff --git a/Realtime/Conversation/LCIMConversation.cs b/Realtime/Conversation/LCIMConversation.cs index d6c76a2..e2ba235 100644 --- a/Realtime/Conversation/LCIMConversation.cs +++ b/Realtime/Conversation/LCIMConversation.cs @@ -384,10 +384,10 @@ namespace LeanCloud.Realtime { CreatorId = co as string; } if (conv.TryGetValue("m", out object mo)) { - ids = new HashSet(mo as List); + ids = new HashSet((mo as IList).Cast()); } if (conv.TryGetValue("mu", out object muo)) { - mutedIds = new HashSet(muo as List); + mutedIds = new HashSet((muo as IList).Cast()); } } diff --git a/Realtime/Internal/Controller/LCIMConversationController.cs b/Realtime/Internal/Controller/LCIMConversationController.cs index f42d2a5..90d4985 100644 --- a/Realtime/Internal/Controller/LCIMConversationController.cs +++ b/Realtime/Internal/Controller/LCIMConversationController.cs @@ -462,6 +462,7 @@ namespace LeanCloud.Realtime.Internal.Controller { conversation = new LCIMConversation(Client); Client.ConversationDict[convId] = conversation; } + conversation.MergeFrom(conv); return conversation; }).ToList().AsReadOnly(); diff --git a/Realtime/Internal/Controller/LCIMMessageController.cs b/Realtime/Internal/Controller/LCIMMessageController.cs index fb18439..1ec3524 100644 --- a/Realtime/Internal/Controller/LCIMMessageController.cs +++ b/Realtime/Internal/Controller/LCIMMessageController.cs @@ -85,8 +85,8 @@ namespace LeanCloud.Realtime.Internal.Controller { } else if (newMessage is LCIMBinaryMessage binaryMessage) { item.BinaryMsg = ByteString.CopyFrom(binaryMessage.Data); } - if (newMessage.MentionList != null) { - item.MentionPids.AddRange(newMessage.MentionList); + if (newMessage.MentionIdList != null) { + item.MentionPids.AddRange(newMessage.MentionIdList); } if (newMessage.MentionAll) { item.MentionAll = newMessage.MentionAll; @@ -146,43 +146,23 @@ namespace LeanCloud.Realtime.Internal.Controller { internal override async Task OnNotification(GenericCommand notification) { DirectCommand direct = notification.DirectMessage; - LCIMMessage message = null; + LCIMMessage message; if (direct.HasBinaryMsg) { // 二进制消息 byte[] bytes = direct.BinaryMsg.ToByteArray(); - message = new LCIMBinaryMessage(bytes); + message = LCIMBinaryMessage.Deserialize(bytes); } else { - // 文本消息 - string messageData = direct.Msg; - Dictionary msgData = JsonConvert.DeserializeObject>(messageData, - new LCJsonConverter()); - int msgType = (int)msgData["_lctype"]; - switch (msgType) { - case -1: - message = new LCIMTextMessage(); - break; - case -2: - message = new LCIMImageMessage(); - break; - case -3: - message = new LCIMAudioMessage(); - break; - case -4: - message = new LCIMVideoMessage(); - break; - case -5: - message = new LCIMLocationMessage(); - break; - case -6: - message = new LCIMFileMessage(); - break; - default: - break; - } - message.Decode(direct); + // 类型消息 + message = LCIMTypedMessage.Deserialize(direct.Msg); } + // 填充消息数据 + message.ConversationId = direct.Cid; + message.Id = direct.Id; + message.FromClientId = direct.FromPeerId; + message.SentTimestamp = direct.Timestamp; // 获取对话 LCIMConversation conversation = await Client.GetOrQueryConversation(direct.Cid); + conversation.LastMessage = message; Client.OnMessage?.Invoke(conversation, message); } diff --git a/Realtime/Internal/Controller/LCIMUnreadController.cs b/Realtime/Internal/Controller/LCIMUnreadController.cs index 2364c8d..76b6018 100644 --- a/Realtime/Internal/Controller/LCIMUnreadController.cs +++ b/Realtime/Internal/Controller/LCIMUnreadController.cs @@ -2,9 +2,7 @@ using System.Threading.Tasks; using System.Collections.Generic; using System.Collections.ObjectModel; -using Newtonsoft.Json; using LeanCloud.Realtime.Protocol; -using LeanCloud.Storage.Internal; namespace LeanCloud.Realtime.Internal.Controller { internal class LCIMUnreadController : LCIMController { @@ -22,35 +20,20 @@ namespace LeanCloud.Realtime.Internal.Controller { Dictionary conversationDict = (await Client.GetConversationList(convIds)) .ToDictionary(item => item.Id); ReadOnlyCollection conversations = unread.Convs.Select(conv => { + // 设置对话中的未读数据 LCIMConversation conversation = conversationDict[conv.Cid]; conversation.Unread = conv.Unread; - // 解析最后一条消息 - Dictionary msgData = JsonConvert.DeserializeObject>(conv.Data, - new LCJsonConverter()); - int msgType = (int)msgData["_lctype"]; + LCIMMessage message = null; - switch (msgType) { - case -1: - message = new LCIMTextMessage(); - break; - case -2: - message = new LCIMImageMessage(); - break; - case -3: - message = new LCIMAudioMessage(); - break; - case -4: - message = new LCIMVideoMessage(); - break; - case -5: - message = new LCIMLocationMessage(); - break; - case -6: - message = new LCIMFileMessage(); - break; - default: - break; + if (conv.HasBinaryMsg) { + // 二进制消息 + byte[] bytes = conv.BinaryMsg.ToByteArray(); + message = LCIMBinaryMessage.Deserialize(bytes); + } else { + // 类型消息 + message = LCIMTypedMessage.Deserialize(conv.Data); } + // 填充消息数据 message.ConversationId = conv.Cid; message.Id = conv.Mid; message.FromClientId = conv.From; diff --git a/Realtime/Message/LCIMBinaryMessage.cs b/Realtime/Message/LCIMBinaryMessage.cs index c720e07..6b590bf 100644 --- a/Realtime/Message/LCIMBinaryMessage.cs +++ b/Realtime/Message/LCIMBinaryMessage.cs @@ -10,5 +10,9 @@ namespace LeanCloud.Realtime { public LCIMBinaryMessage(byte[] data) { Data = data; } + + internal static LCIMBinaryMessage Deserialize(byte[] bytes) { + return new LCIMBinaryMessage(bytes); + } } } diff --git a/Realtime/Message/LCIMMessage.cs b/Realtime/Message/LCIMMessage.cs index 1edd163..3337dec 100644 --- a/Realtime/Message/LCIMMessage.cs +++ b/Realtime/Message/LCIMMessage.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Collections.Generic; using LeanCloud.Realtime.Protocol; @@ -67,7 +68,7 @@ namespace LeanCloud.Realtime { } } - public List MentionList { + public List MentionIdList { get; set; } @@ -75,14 +76,11 @@ namespace LeanCloud.Realtime { get; set; } - internal LCIMMessage() { + public bool Mentioned { + get; internal set; } - internal virtual void Decode(DirectCommand direct) { - ConversationId = direct.Cid; - Id = direct.Id; - FromClientId = direct.FromPeerId; - SentTimestamp = direct.Timestamp; + internal LCIMMessage() { } } } diff --git a/Realtime/Message/LCIMTypedMessage.cs b/Realtime/Message/LCIMTypedMessage.cs index 7152dd7..fb0a61b 100644 --- a/Realtime/Message/LCIMTypedMessage.cs +++ b/Realtime/Message/LCIMTypedMessage.cs @@ -1,8 +1,7 @@ using System.Collections.Generic; using Newtonsoft.Json; -using LeanCloud.Realtime.Protocol; -using LeanCloud.Storage.Internal; using LeanCloud.Storage.Internal.Codec; +using LeanCloud.Storage.Internal; namespace LeanCloud.Realtime { public abstract class LCIMTypedMessage : LCIMMessage { @@ -40,12 +39,6 @@ namespace LeanCloud.Realtime { return msgData; } - internal override void Decode(DirectCommand direct) { - base.Decode(direct); - Dictionary msgData = JsonConvert.DeserializeObject>(direct.Msg, new LCJsonConverter()); - DecodeMessageData(msgData); - } - protected virtual void DecodeMessageData(Dictionary msgData) { MessageType = (int)msgData["_lctype"]; if (msgData.TryGetValue("_lcattrs", out object attrObj)) { @@ -53,9 +46,11 @@ namespace LeanCloud.Realtime { } } - internal static LCIMTypedMessage Deserialize(Dictionary messageData) { + internal static LCIMTypedMessage Deserialize(string json) { + Dictionary msgData = JsonConvert.DeserializeObject>(json, + new LCJsonConverter()); LCIMTypedMessage message = null; - int msgType = (int)messageData["_lctype"]; + int msgType = (int)msgData["_lctype"]; switch (msgType) { case -1: message = new LCIMTextMessage(); @@ -76,9 +71,11 @@ namespace LeanCloud.Realtime { message = new LCIMFileMessage(); break; default: + // TODO 用户自定义类型消息 + break; } - //message.Decode(direct); + message.DecodeMessageData(msgData); return message; } } diff --git a/Test/Realtime.Test/Conversation.cs b/Test/Realtime.Test/Conversation.cs index 102184a..5769bef 100644 --- a/Test/Realtime.Test/Conversation.cs +++ b/Test/Realtime.Test/Conversation.cs @@ -111,10 +111,11 @@ namespace Realtime.Test { string otherId = Guid.NewGuid().ToString(); LCIMConversation conversation = await client.CreateConversation(new List { otherId }); - conversation.Name = "leancloud"; - conversation["k1"] = "v1"; - conversation["k2"] = "v2"; - await conversation.UpdateInfo(); + await conversation.UpdateInfo(new Dictionary { + { "name", "leancloud" }, + { "k1", "v1" }, + { "k2", "v2" } + }); Assert.AreEqual(conversation.Name, "leancloud"); Assert.AreEqual(conversation["k1"], "v1");