From 71d1bff27d25f47b38cd59975af777090b0c2735 Mon Sep 17 00:00:00 2001 From: oneRain Date: Tue, 15 Jun 2021 12:30:30 +0800 Subject: [PATCH 1/2] fix: conv reads when last message is null. --- .../Internal/Controller/LCIMMessageController.cs | 9 ++++++--- .../Realtime/Public/Conversation/LCIMConversation.cs | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Realtime/Realtime/Internal/Controller/LCIMMessageController.cs b/Realtime/Realtime/Internal/Controller/LCIMMessageController.cs index f9a3f2a..be64e0e 100644 --- a/Realtime/Realtime/Internal/Controller/LCIMMessageController.cs +++ b/Realtime/Realtime/Internal/Controller/LCIMMessageController.cs @@ -186,10 +186,13 @@ namespace LeanCloud.Realtime.Internal.Controller { LCIMMessage msg) { ReadCommand read = new ReadCommand(); ReadTuple tuple = new ReadTuple { - Cid = convId, - Mid = msg.Id, - Timestamp = msg.SentTimestamp + Cid = convId }; + // 当不传 msg 时,服务端将其收到的最后一条消息标记为已读,可能与客户端不一致 + if (msg != null) { + tuple.Mid = msg.Id; + tuple.Timestamp = msg.SentTimestamp; + } read.Convs.Add(tuple); GenericCommand command = NewCommand(CommandType.Read); command.ReadMessage = read; diff --git a/Realtime/Realtime/Public/Conversation/LCIMConversation.cs b/Realtime/Realtime/Public/Conversation/LCIMConversation.cs index 77cb321..cff93b0 100644 --- a/Realtime/Realtime/Public/Conversation/LCIMConversation.cs +++ b/Realtime/Realtime/Public/Conversation/LCIMConversation.cs @@ -185,7 +185,7 @@ namespace LeanCloud.Realtime { /// /// public virtual async Task Read() { - if (LastMessage == null) { + if (Unread == 0) { return; } await Client.MessageController.Read(Id, LastMessage); From 9e3e736b935c2b3d6b681c806a2704334d633641 Mon Sep 17 00:00:00 2001 From: oneRain Date: Tue, 15 Jun 2021 13:59:42 +0800 Subject: [PATCH 2/2] chore: get or query conversations. --- .../Internal/Connection/LCConnection.cs | 2 +- Realtime/Realtime/Public/LCIMClient.cs | 93 ++++++++++++------- 2 files changed, 62 insertions(+), 33 deletions(-) diff --git a/Realtime/Realtime/Internal/Connection/LCConnection.cs b/Realtime/Realtime/Internal/Connection/LCConnection.cs index e724b26..25845f2 100644 --- a/Realtime/Realtime/Internal/Connection/LCConnection.cs +++ b/Realtime/Realtime/Internal/Connection/LCConnection.cs @@ -168,6 +168,7 @@ namespace LeanCloud.Realtime.Internal.Connection { // 应答 int requestIndex = command.I; if (requestToResponses.TryGetValue(command, out TaskCompletionSource tcs)) { + requestToResponses.Remove(command); if (command.HasErrorMessage) { // 错误 ErrorCommand error = command.ErrorMessage; @@ -179,7 +180,6 @@ namespace LeanCloud.Realtime.Internal.Connection { } else { tcs.TrySetResult(command); } - requestToResponses.Remove(command); } else { LCLogger.Error($"No request for {requestIndex}"); } diff --git a/Realtime/Realtime/Public/LCIMClient.cs b/Realtime/Realtime/Public/LCIMClient.cs index 0d33627..c7bb338 100644 --- a/Realtime/Realtime/Public/LCIMClient.cs +++ b/Realtime/Realtime/Public/LCIMClient.cs @@ -384,21 +384,12 @@ namespace LeanCloud.Realtime { if (string.IsNullOrEmpty(id)) { throw new ArgumentNullException(nameof(id)); } - if (LCIMConversation.IsTemporayConversation(id)) { - List temporaryConversationList = await ConversationController.GetTemporaryConversations(new string[] { id }); - if (temporaryConversationList == null || temporaryConversationList.Count < 1) { - return null; - } - return temporaryConversationList[0]; - } - LCIMConversationQuery query = GetQuery() - .WhereEqualTo("objectId", id) - .Limit(1); - ReadOnlyCollection results = await ConversationController.Find(query); - if (results == null || results.Count < 1) { + + ReadOnlyCollection convs = await GetConversationList(new string[] { id }); + if (convs == null || convs.Count() == 0) { return null; } - return results[0]; + return convs.First(); } /// @@ -410,26 +401,12 @@ namespace LeanCloud.Realtime { if (ids == null || ids.Count() == 0) { throw new ArgumentNullException(nameof(ids)); } - // 区分临时对话 - IEnumerable tempConvIds = ids.Where(item => { - return LCIMConversation.IsTemporayConversation(item); - }); - IEnumerable convIds = ids.Where(item => { - return !tempConvIds.Contains(item); - }); - List conversationList = new List(); - if (tempConvIds.Count() > 0) { - List temporaryConversations = await ConversationController.GetTemporaryConversations(tempConvIds); - conversationList.AddRange(temporaryConversations); + + IEnumerable convs = await GetOrQueryConversations(ids); + if (convs == null) { + return default; } - if (convIds.Count() > 0) { - LCIMConversationQuery query = GetQuery() - .WhereContainedIn("objectId", convIds) - .Limit(convIds.Count()); - ReadOnlyCollection conversations = await ConversationController.Find(query); - conversationList.AddRange(conversations); - } - return conversationList.AsReadOnly(); + return convs.ToList().AsReadOnly(); } /// @@ -485,5 +462,57 @@ namespace LeanCloud.Realtime { conversation = await GetConversation(convId); return conversation; } + + internal async Task> GetOrQueryConversations(IEnumerable ids) { + if (ids == null || ids.Count() == 0) { + return default; + } + + List convs = new List(); + // 区分是否是缓存对话 + IEnumerable cachedConvIds = ids.Where(id => ConversationDict.ContainsKey(id)); + IEnumerable noCachedConvIds = ids.Except(cachedConvIds); + + // 查找对话缓存 + IEnumerable cachedConvs = cachedConvIds.Select(id => { + return ConversationDict[id]; + }); + if (cachedConvs != null && cachedConvs.Count() > 0) { + convs.AddRange(cachedConvs); + } + + // 区分临时对话 + IEnumerable queriedConvs = await QueryConversations(noCachedConvIds); + if (queriedConvs != null && queriedConvs.Count() > 0) { + convs.AddRange(queriedConvs); + } + + return convs; + } + + internal async Task> QueryConversations(IEnumerable ids) { + if (ids == null || ids.Count() == 0) { + return default; + } + + List convs = new List(); + // 区分临时对话 + IEnumerable tempConvIds = ids.Where(item => { + return LCIMConversation.IsTemporayConversation(item); + }); + IEnumerable convIds = ids.Except(tempConvIds); + if (tempConvIds.Count() > 0) { + List temporaryConversations = await ConversationController.GetTemporaryConversations(tempConvIds); + convs.AddRange(temporaryConversations); + } + if (convIds.Count() > 0) { + LCIMConversationQuery query = GetQuery() + .WhereContainedIn("objectId", convIds) + .Limit(convIds.Count()); + ReadOnlyCollection conversations = await ConversationController.Find(query); + convs.AddRange(conversations); + } + return convs; + } } }